@umituz/react-native-auth 3.4.15 → 3.4.19
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-auth",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.19",
|
|
4
4
|
"description": "Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design with dependency injection, configurable validation, and comprehensive error handling.",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -36,10 +36,9 @@
|
|
|
36
36
|
"@umituz/react-native-localization": "latest",
|
|
37
37
|
"@umituz/react-native-storage": "latest",
|
|
38
38
|
"@umituz/react-native-tanstack": "latest",
|
|
39
|
-
"@umituz/react-native-validation": "
|
|
39
|
+
"@umituz/react-native-validation": "^1.4.7"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@gorhom/bottom-sheet": ">=4.0.0",
|
|
43
42
|
"@react-navigation/native": ">=6.0.0",
|
|
44
43
|
"@react-navigation/stack": ">=6.0.0",
|
|
45
44
|
"@tanstack/react-query": ">=5.0.0",
|
|
@@ -50,15 +49,13 @@
|
|
|
50
49
|
"react": ">=18.2.0",
|
|
51
50
|
"react-native": ">=0.74.0",
|
|
52
51
|
"react-native-gesture-handler": ">=2.0.0",
|
|
53
|
-
"react-native-reanimated": ">=3.0.0",
|
|
54
52
|
"react-native-safe-area-context": ">=4.0.0",
|
|
55
53
|
"react-native-svg": ">=13.0.0",
|
|
56
54
|
"zustand": ">=4.0.0"
|
|
57
55
|
},
|
|
58
56
|
"devDependencies": {
|
|
59
57
|
"@expo/vector-icons": "^15.0.3",
|
|
60
|
-
"@
|
|
61
|
-
"@react-native-async-storage/async-storage": "^1.24.0",
|
|
58
|
+
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
62
59
|
"@react-native-community/datetimepicker": "^8.5.1",
|
|
63
60
|
"@react-navigation/bottom-tabs": "^7.9.0",
|
|
64
61
|
"@react-navigation/native": "^7.1.26",
|
|
@@ -68,15 +65,11 @@
|
|
|
68
65
|
"@types/react": "~19.1.0",
|
|
69
66
|
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
70
67
|
"@typescript-eslint/parser": "^7.0.0",
|
|
71
|
-
"@umituz/react-native-design-system": "
|
|
68
|
+
"@umituz/react-native-design-system": "latest",
|
|
72
69
|
"@umituz/react-native-design-system-theme": "latest",
|
|
73
|
-
"@umituz/react-native-
|
|
70
|
+
"@umituz/react-native-filesystem": "latest",
|
|
74
71
|
"@umituz/react-native-haptics": "latest",
|
|
75
|
-
"@umituz/react-native-localization": "latest",
|
|
76
|
-
"@umituz/react-native-storage": "latest",
|
|
77
|
-
"@umituz/react-native-tanstack": "latest",
|
|
78
72
|
"@umituz/react-native-uuid": "latest",
|
|
79
|
-
"@umituz/react-native-validation": "latest",
|
|
80
73
|
"eslint": "^8.57.0",
|
|
81
74
|
"expo-apple-authentication": "^6.0.0",
|
|
82
75
|
"expo-application": "^7.0.8",
|
|
@@ -93,7 +86,6 @@
|
|
|
93
86
|
"react": "~19.1.0",
|
|
94
87
|
"react-native": "~0.81.5",
|
|
95
88
|
"react-native-gesture-handler": "^2.0.0",
|
|
96
|
-
"react-native-reanimated": "^3.0.0",
|
|
97
89
|
"react-native-safe-area-context": "^4.0.0",
|
|
98
90
|
"react-native-svg": "^15.15.1",
|
|
99
91
|
"rn-emoji-keyboard": "^1.7.0",
|
|
@@ -3,15 +3,16 @@
|
|
|
3
3
|
* Bottom sheet modal for authentication (Login/Register)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React, { useEffect, useCallback, useRef, useState
|
|
7
|
-
import { View, TouchableOpacity } from "react-native";
|
|
6
|
+
import React, { useEffect, useCallback, useRef, useState } from "react";
|
|
7
|
+
import { View, TouchableOpacity, ScrollView } from "react-native";
|
|
8
8
|
import {
|
|
9
|
+
useAppDesignTokens,
|
|
10
|
+
AtomicText,
|
|
11
|
+
AtomicIcon,
|
|
12
|
+
AtomicKeyboardAvoidingView,
|
|
9
13
|
BottomSheetModal,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from "@gorhom/bottom-sheet";
|
|
13
|
-
import type { BottomSheetBackdropProps } from "@gorhom/bottom-sheet";
|
|
14
|
-
import { useAppDesignTokens, AtomicText, AtomicIcon } from "@umituz/react-native-design-system";
|
|
14
|
+
type BottomSheetModalRef,
|
|
15
|
+
} from "@umituz/react-native-design-system";
|
|
15
16
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
16
17
|
import { useAuthModalStore } from "../stores/authModalStore";
|
|
17
18
|
import { useAuth } from "../hooks/useAuth";
|
|
@@ -45,7 +46,7 @@ export const AuthBottomSheet: React.FC<AuthBottomSheetProps> = ({
|
|
|
45
46
|
}) => {
|
|
46
47
|
const tokens = useAppDesignTokens();
|
|
47
48
|
const { t } = useLocalization();
|
|
48
|
-
const modalRef = useRef<
|
|
49
|
+
const modalRef = useRef<BottomSheetModalRef>(null);
|
|
49
50
|
|
|
50
51
|
const [googleLoading, setGoogleLoading] = useState(false);
|
|
51
52
|
const [appleLoading, setAppleLoading] = useState(false);
|
|
@@ -107,33 +108,21 @@ export const AuthBottomSheet: React.FC<AuthBottomSheetProps> = ({
|
|
|
107
108
|
}
|
|
108
109
|
}, [onAppleSignIn]);
|
|
109
110
|
|
|
110
|
-
const renderBackdrop = useCallback(
|
|
111
|
-
(props: BottomSheetBackdropProps) => (
|
|
112
|
-
<BottomSheetBackdrop {...props} appearsOnIndex={0} disappearsOnIndex={-1} pressBehavior="close" />
|
|
113
|
-
),
|
|
114
|
-
[],
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
const snapPoints = useMemo(() => ["95%"], []);
|
|
118
|
-
|
|
119
111
|
return (
|
|
120
112
|
<BottomSheetModal
|
|
121
113
|
ref={modalRef}
|
|
122
|
-
index={0}
|
|
123
|
-
snapPoints={snapPoints}
|
|
124
|
-
backdropComponent={renderBackdrop}
|
|
125
114
|
onDismiss={handleDismiss}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
keyboardBlurBehavior="restore"
|
|
129
|
-
backgroundStyle={[styles.background, { backgroundColor: tokens.colors.backgroundPrimary }]}
|
|
130
|
-
handleIndicatorStyle={[styles.handleIndicator, { backgroundColor: tokens.colors.border }]}
|
|
115
|
+
preset="full"
|
|
116
|
+
backgroundColor={tokens.colors.backgroundPrimary}
|
|
131
117
|
>
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
showsVerticalScrollIndicator={false}
|
|
135
|
-
keyboardShouldPersistTaps="handled"
|
|
118
|
+
<AtomicKeyboardAvoidingView
|
|
119
|
+
style={{ flex: 1 }}
|
|
136
120
|
>
|
|
121
|
+
<ScrollView
|
|
122
|
+
contentContainerStyle={styles.scrollContent}
|
|
123
|
+
showsVerticalScrollIndicator={false}
|
|
124
|
+
keyboardShouldPersistTaps="handled"
|
|
125
|
+
>
|
|
137
126
|
<TouchableOpacity
|
|
138
127
|
style={styles.closeButton}
|
|
139
128
|
onPress={handleClose}
|
|
@@ -176,7 +165,8 @@ export const AuthBottomSheet: React.FC<AuthBottomSheetProps> = ({
|
|
|
176
165
|
/>
|
|
177
166
|
)}
|
|
178
167
|
</View>
|
|
179
|
-
</
|
|
168
|
+
</ScrollView>
|
|
169
|
+
</AtomicKeyboardAvoidingView>
|
|
180
170
|
</BottomSheetModal>
|
|
181
171
|
);
|
|
182
172
|
};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Single Responsibility: Render login form UI
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React from "react";
|
|
7
|
-
import { View, StyleSheet } from "react-native";
|
|
6
|
+
import React, { useRef } from "react";
|
|
7
|
+
import { View, StyleSheet, TextInput } from "react-native";
|
|
8
8
|
import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
|
|
9
9
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
10
10
|
import { useLoginForm } from "../hooks/useLoginForm";
|
|
@@ -17,6 +17,7 @@ interface LoginFormProps {
|
|
|
17
17
|
|
|
18
18
|
export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) => {
|
|
19
19
|
const { t } = useLocalization();
|
|
20
|
+
const passwordRef = useRef<TextInput>(null);
|
|
20
21
|
const {
|
|
21
22
|
email,
|
|
22
23
|
password,
|
|
@@ -42,20 +43,27 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
|
|
|
42
43
|
disabled={loading}
|
|
43
44
|
state={emailError ? "error" : "default"}
|
|
44
45
|
helperText={emailError || undefined}
|
|
46
|
+
returnKeyType="next"
|
|
47
|
+
onSubmitEditing={() => passwordRef.current?.focus()}
|
|
48
|
+
blurOnSubmit={false}
|
|
45
49
|
/>
|
|
46
50
|
</View>
|
|
47
51
|
|
|
48
52
|
<View style={styles.inputContainer}>
|
|
49
53
|
<AtomicInput
|
|
54
|
+
ref={passwordRef}
|
|
50
55
|
label={t("auth.password")}
|
|
51
56
|
value={password}
|
|
52
57
|
onChangeText={handlePasswordChange}
|
|
53
58
|
placeholder={t("auth.passwordPlaceholder")}
|
|
54
59
|
secureTextEntry
|
|
60
|
+
showPasswordToggle
|
|
55
61
|
autoCapitalize="none"
|
|
56
62
|
disabled={loading}
|
|
57
63
|
state={passwordError ? "error" : "default"}
|
|
58
64
|
helperText={passwordError || undefined}
|
|
65
|
+
returnKeyType="done"
|
|
66
|
+
onSubmitEditing={() => { void handleSignIn(); }}
|
|
59
67
|
/>
|
|
60
68
|
</View>
|
|
61
69
|
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Single Responsibility: Render register form UI
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React from "react";
|
|
7
|
-
import { View, StyleSheet } from "react-native";
|
|
6
|
+
import React, { useRef } from "react";
|
|
7
|
+
import { View, StyleSheet, TextInput } from "react-native";
|
|
8
8
|
import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
|
|
9
9
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
10
10
|
import { useRegisterForm } from "../hooks/useRegisterForm";
|
|
@@ -30,6 +30,10 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
|
|
|
30
30
|
onPrivacyPress,
|
|
31
31
|
}) => {
|
|
32
32
|
const { t } = useLocalization();
|
|
33
|
+
const emailRef = useRef<TextInput>(null);
|
|
34
|
+
const passwordRef = useRef<TextInput>(null);
|
|
35
|
+
const confirmPasswordRef = useRef<TextInput>(null);
|
|
36
|
+
|
|
33
37
|
const {
|
|
34
38
|
displayName,
|
|
35
39
|
email,
|
|
@@ -61,11 +65,15 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
|
|
|
61
65
|
disabled={loading}
|
|
62
66
|
state={fieldErrors.displayName ? "error" : "default"}
|
|
63
67
|
helperText={fieldErrors.displayName || undefined}
|
|
68
|
+
returnKeyType="next"
|
|
69
|
+
onSubmitEditing={() => emailRef.current?.focus()}
|
|
70
|
+
blurOnSubmit={false}
|
|
64
71
|
/>
|
|
65
72
|
</View>
|
|
66
73
|
|
|
67
74
|
<View style={styles.inputContainer}>
|
|
68
75
|
<AtomicInput
|
|
76
|
+
ref={emailRef}
|
|
69
77
|
label={t("auth.email")}
|
|
70
78
|
value={email}
|
|
71
79
|
onChangeText={handleEmailChange}
|
|
@@ -75,20 +83,28 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
|
|
|
75
83
|
disabled={loading}
|
|
76
84
|
state={fieldErrors.email ? "error" : "default"}
|
|
77
85
|
helperText={fieldErrors.email || undefined}
|
|
86
|
+
returnKeyType="next"
|
|
87
|
+
onSubmitEditing={() => passwordRef.current?.focus()}
|
|
88
|
+
blurOnSubmit={false}
|
|
78
89
|
/>
|
|
79
90
|
</View>
|
|
80
91
|
|
|
81
92
|
<View style={styles.inputContainer}>
|
|
82
93
|
<AtomicInput
|
|
94
|
+
ref={passwordRef}
|
|
83
95
|
label={t("auth.password")}
|
|
84
96
|
value={password}
|
|
85
97
|
onChangeText={handlePasswordChange}
|
|
86
98
|
placeholder={t("auth.passwordPlaceholder")}
|
|
87
99
|
secureTextEntry
|
|
100
|
+
showPasswordToggle
|
|
88
101
|
autoCapitalize="none"
|
|
89
102
|
disabled={loading}
|
|
90
103
|
state={fieldErrors.password ? "error" : "default"}
|
|
91
104
|
helperText={fieldErrors.password || undefined}
|
|
105
|
+
returnKeyType="next"
|
|
106
|
+
onSubmitEditing={() => confirmPasswordRef.current?.focus()}
|
|
107
|
+
blurOnSubmit={false}
|
|
92
108
|
/>
|
|
93
109
|
{password.length > 0 && (
|
|
94
110
|
<PasswordStrengthIndicator requirements={passwordRequirements} />
|
|
@@ -97,6 +113,7 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
|
|
|
97
113
|
|
|
98
114
|
<View style={styles.inputContainer}>
|
|
99
115
|
<AtomicInput
|
|
116
|
+
ref={confirmPasswordRef}
|
|
100
117
|
label={t("auth.confirmPassword")}
|
|
101
118
|
value={confirmPassword}
|
|
102
119
|
onChangeText={handleConfirmPasswordChange}
|
|
@@ -104,10 +121,13 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
|
|
|
104
121
|
t("auth.confirmPasswordPlaceholder")
|
|
105
122
|
}
|
|
106
123
|
secureTextEntry
|
|
124
|
+
showPasswordToggle
|
|
107
125
|
autoCapitalize="none"
|
|
108
126
|
disabled={loading}
|
|
109
127
|
state={fieldErrors.confirmPassword ? "error" : "default"}
|
|
110
128
|
helperText={fieldErrors.confirmPassword || undefined}
|
|
129
|
+
returnKeyType="done"
|
|
130
|
+
onSubmitEditing={() => { void handleSignUp(); }}
|
|
111
131
|
/>
|
|
112
132
|
{confirmPassword.length > 0 && (
|
|
113
133
|
<PasswordMatchIndicator isMatch={passwordsMatch} />
|