@umituz/react-native-auth 4.3.95 → 4.3.96
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": "4.3.
|
|
3
|
+
"version": "4.3.96",
|
|
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",
|
package/src/index.ts
CHANGED
|
@@ -166,9 +166,15 @@ export type { UseLocalErrorResult } from './presentation/hooks/useLocalError';
|
|
|
166
166
|
export { AuthProvider } from './presentation/providers/AuthProvider';
|
|
167
167
|
export type { ErrorFallbackProps } from './presentation/providers/AuthProvider';
|
|
168
168
|
export { LoginScreen } from './presentation/screens/LoginScreen';
|
|
169
|
-
export type {
|
|
169
|
+
export type {
|
|
170
|
+
LoginScreenProps,
|
|
171
|
+
LoginScreenTranslations,
|
|
172
|
+
} from './presentation/screens/LoginScreen';
|
|
170
173
|
export { RegisterScreen } from './presentation/screens/RegisterScreen';
|
|
171
|
-
export type {
|
|
174
|
+
export type {
|
|
175
|
+
RegisterScreenProps,
|
|
176
|
+
RegisterScreenTranslations,
|
|
177
|
+
} from './presentation/screens/RegisterScreen';
|
|
172
178
|
export { AccountScreen } from './presentation/screens/AccountScreen';
|
|
173
179
|
export type {
|
|
174
180
|
AccountScreenProps,
|
|
@@ -183,12 +189,20 @@ export type {
|
|
|
183
189
|
PasswordPromptScreenProps,
|
|
184
190
|
} from './presentation/screens/PasswordPromptScreen';
|
|
185
191
|
export { AuthNavigator } from './presentation/navigation/AuthNavigator';
|
|
186
|
-
export type {
|
|
192
|
+
export type {
|
|
193
|
+
AuthStackParamList,
|
|
194
|
+
AuthNavigatorProps,
|
|
195
|
+
AuthNavigatorTranslations,
|
|
196
|
+
} from './presentation/navigation/AuthNavigator';
|
|
187
197
|
export { AuthBottomSheet } from './presentation/components/AuthBottomSheet';
|
|
188
198
|
export type {
|
|
189
199
|
AuthBottomSheetProps,
|
|
190
200
|
AuthBottomSheetTranslations,
|
|
191
201
|
} from './presentation/components/AuthBottomSheet';
|
|
202
|
+
export { SocialLoginButtons } from './presentation/components/SocialLoginButtons';
|
|
203
|
+
export type {
|
|
204
|
+
SocialLoginButtonsTranslations,
|
|
205
|
+
} from './presentation/components/SocialLoginButtons';
|
|
192
206
|
export { ProfileSection } from './presentation/components/ProfileSection';
|
|
193
207
|
export type {
|
|
194
208
|
ProfileSectionProps,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
2
2
|
import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
|
|
3
3
|
import { StackNavigator, type StackNavigatorConfig, type StackScreenProps } from "@umituz/react-native-design-system/molecules";
|
|
4
4
|
import { storageRepository, unwrap } from "@umituz/react-native-design-system/storage";
|
|
5
|
+
import type { SocialAuthConfiguration } from "../hooks/useAuthBottomSheet";
|
|
5
6
|
import { LoginScreen, type LoginScreenTranslations } from "../screens/LoginScreen";
|
|
6
7
|
import { RegisterScreen, type RegisterScreenTranslations } from "../screens/RegisterScreen";
|
|
7
8
|
|
|
@@ -10,28 +11,28 @@ export type AuthStackParamList = {
|
|
|
10
11
|
Register: undefined;
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
// Storage key for persisting initial route preference across navigation
|
|
13
15
|
const SHOW_REGISTER_KEY = "auth_show_register";
|
|
14
16
|
|
|
15
|
-
interface AuthNavigatorTranslations {
|
|
17
|
+
export interface AuthNavigatorTranslations {
|
|
16
18
|
login: LoginScreenTranslations;
|
|
17
19
|
register: RegisterScreenTranslations;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
interface AuthNavigatorProps {
|
|
22
|
+
export interface AuthNavigatorProps {
|
|
21
23
|
translations: AuthNavigatorTranslations;
|
|
22
24
|
termsUrl?: string;
|
|
23
25
|
privacyUrl?: string;
|
|
24
26
|
onTermsPress?: () => void;
|
|
25
27
|
onPrivacyPress?: () => void;
|
|
28
|
+
socialConfig?: SocialAuthConfiguration;
|
|
29
|
+
onGoogleSignIn?: () => Promise<void>;
|
|
30
|
+
onAppleSignIn?: () => Promise<void>;
|
|
31
|
+
renderLogo?: () => React.ReactNode;
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
export const AuthNavigator: React.FC<AuthNavigatorProps> = ({
|
|
29
|
-
translations,
|
|
30
|
-
termsUrl,
|
|
31
|
-
privacyUrl,
|
|
32
|
-
onTermsPress,
|
|
33
|
-
onPrivacyPress,
|
|
34
|
-
}) => {
|
|
34
|
+
export const AuthNavigator: React.FC<AuthNavigatorProps> = (props) => {
|
|
35
|
+
const { translations, termsUrl, privacyUrl, onTermsPress, onPrivacyPress, socialConfig, onGoogleSignIn, onAppleSignIn, renderLogo } = props;
|
|
35
36
|
const tokens = useAppDesignTokens();
|
|
36
37
|
const [initialRouteName, setInitialRouteName] = useState<
|
|
37
38
|
"Login" | "Register" | undefined
|
|
@@ -77,29 +78,42 @@ export const AuthNavigator: React.FC<AuthNavigatorProps> = ({
|
|
|
77
78
|
const loginTranslations = useMemo(() => translations.login, [translations.login]);
|
|
78
79
|
const registerTranslations = useMemo(() => translations.register, [translations.register]);
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
// Memoize social auth props
|
|
82
|
+
const socialAuthProps = useMemo(() => ({
|
|
83
|
+
socialConfig,
|
|
84
|
+
onGoogleSignIn,
|
|
85
|
+
onAppleSignIn,
|
|
86
|
+
renderLogo,
|
|
87
|
+
}), [socialConfig, onGoogleSignIn, onAppleSignIn, renderLogo]);
|
|
88
|
+
|
|
89
|
+
// Create screen components with proper types
|
|
90
|
+
const LoginScreenComponent = useMemo(() => {
|
|
91
|
+
// Use FC with generic props to satisfy StackNavigator type, then cast for internal use
|
|
92
|
+
const LoginScreenWrapper: React.FC<{ navigation: unknown; route: unknown }> = (props) => (
|
|
82
93
|
<LoginScreen
|
|
83
|
-
{...props}
|
|
94
|
+
{...(props as StackScreenProps<AuthStackParamList, 'Login'>)}
|
|
84
95
|
translations={loginTranslations}
|
|
96
|
+
{...socialAuthProps}
|
|
85
97
|
/>
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
);
|
|
98
|
+
);
|
|
99
|
+
return React.memo(LoginScreenWrapper);
|
|
100
|
+
}, [loginTranslations, socialAuthProps]);
|
|
89
101
|
|
|
90
|
-
const
|
|
91
|
-
|
|
102
|
+
const RegisterScreenComponent = useMemo(() => {
|
|
103
|
+
// Use FC with generic props to satisfy StackNavigator type, then cast for internal use
|
|
104
|
+
const RegisterScreenWrapper: React.FC<{ navigation: unknown; route: unknown }> = (props) => (
|
|
92
105
|
<RegisterScreen
|
|
93
|
-
{...props}
|
|
106
|
+
{...(props as StackScreenProps<AuthStackParamList, 'Register'>)}
|
|
94
107
|
translations={registerTranslations}
|
|
95
108
|
termsUrl={termsUrl}
|
|
96
109
|
privacyUrl={privacyUrl}
|
|
97
110
|
onTermsPress={onTermsPress}
|
|
98
111
|
onPrivacyPress={onPrivacyPress}
|
|
112
|
+
{...socialAuthProps}
|
|
99
113
|
/>
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
);
|
|
114
|
+
);
|
|
115
|
+
return React.memo(RegisterScreenWrapper);
|
|
116
|
+
}, [registerTranslations, termsUrl, privacyUrl, onTermsPress, onPrivacyPress, socialAuthProps]);
|
|
103
117
|
|
|
104
118
|
if (initialRouteName === undefined) {
|
|
105
119
|
return null;
|
|
@@ -112,8 +126,8 @@ export const AuthNavigator: React.FC<AuthNavigatorProps> = ({
|
|
|
112
126
|
cardStyle: { backgroundColor: tokens.colors.backgroundPrimary },
|
|
113
127
|
},
|
|
114
128
|
screens: [
|
|
115
|
-
{ name: "Login", component:
|
|
116
|
-
{ name: "Register", component:
|
|
129
|
+
{ name: "Login", component: LoginScreenComponent },
|
|
130
|
+
{ name: "Register", component: RegisterScreenComponent },
|
|
117
131
|
],
|
|
118
132
|
};
|
|
119
133
|
|
|
@@ -1,29 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Login Screen Component
|
|
3
|
-
* Login form screen with navigation
|
|
3
|
+
* Login form screen with navigation and social auth support
|
|
4
4
|
* PERFORMANCE: Memoized to prevent unnecessary re-renders
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { memo, useCallback } from "react";
|
|
7
|
+
import React, { memo, useCallback, useMemo } from "react";
|
|
8
|
+
import { View, StyleSheet } from "react-native";
|
|
8
9
|
import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
|
|
9
10
|
import { AtomicCard } from "@umituz/react-native-design-system/atoms";
|
|
10
11
|
import { useAppNavigation } from "@umituz/react-native-design-system/molecules";
|
|
11
12
|
import { ScreenLayout } from "@umituz/react-native-design-system/layouts";
|
|
12
13
|
import { useResponsive } from "@umituz/react-native-design-system/responsive";
|
|
14
|
+
import type { SocialAuthConfiguration } from "../hooks/useAuthBottomSheet";
|
|
15
|
+
import type { SocialAuthProvider } from "../../domain/value-objects/AuthConfig";
|
|
13
16
|
import { AuthHeader } from "../components/AuthHeader";
|
|
14
17
|
import { LoginForm, type LoginFormTranslations } from "../components/LoginForm";
|
|
18
|
+
import { SocialLoginButtons, type SocialLoginButtonsTranslations } from "../components/SocialLoginButtons";
|
|
15
19
|
|
|
16
20
|
export interface LoginScreenTranslations {
|
|
17
21
|
title: string;
|
|
18
22
|
subtitle?: string;
|
|
19
23
|
form: LoginFormTranslations;
|
|
24
|
+
socialButtons?: SocialLoginButtonsTranslations;
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export interface LoginScreenProps {
|
|
23
28
|
translations: LoginScreenTranslations;
|
|
29
|
+
socialConfig?: SocialAuthConfiguration;
|
|
30
|
+
onGoogleSignIn?: () => Promise<void>;
|
|
31
|
+
onAppleSignIn?: () => Promise<void>;
|
|
32
|
+
renderLogo?: () => React.ReactNode;
|
|
24
33
|
}
|
|
25
34
|
|
|
26
|
-
export const LoginScreen = memo<LoginScreenProps>(({
|
|
35
|
+
export const LoginScreen = memo<LoginScreenProps>(({
|
|
36
|
+
translations,
|
|
37
|
+
socialConfig,
|
|
38
|
+
onGoogleSignIn,
|
|
39
|
+
onAppleSignIn,
|
|
40
|
+
renderLogo,
|
|
41
|
+
}) => {
|
|
27
42
|
const navigation = useAppNavigation();
|
|
28
43
|
const tokens = useAppDesignTokens();
|
|
29
44
|
const responsive = useResponsive();
|
|
@@ -33,6 +48,35 @@ export const LoginScreen = memo<LoginScreenProps>(({ translations }) => {
|
|
|
33
48
|
navigation.navigate("Register");
|
|
34
49
|
}, [navigation]);
|
|
35
50
|
|
|
51
|
+
// Determine enabled social providers
|
|
52
|
+
const enabledProviders = useMemo<SocialAuthProvider[]>(() => {
|
|
53
|
+
if (!socialConfig) return [];
|
|
54
|
+
const providers: SocialAuthProvider[] = [];
|
|
55
|
+
// For Google, check if config exists
|
|
56
|
+
if (socialConfig.google) providers.push("google");
|
|
57
|
+
// For Apple, check if enabled flag is true
|
|
58
|
+
if (socialConfig.apple?.enabled) providers.push("apple");
|
|
59
|
+
return providers;
|
|
60
|
+
}, [socialConfig]);
|
|
61
|
+
|
|
62
|
+
const hasSocialAuth = enabledProviders.length > 0 && translations.socialButtons;
|
|
63
|
+
// Check if required handlers exist for enabled providers (only need handler if provider is enabled)
|
|
64
|
+
const hasGoogle = enabledProviders.includes("google") && onGoogleSignIn;
|
|
65
|
+
const hasApple = enabledProviders.includes("apple") && onAppleSignIn;
|
|
66
|
+
const showSocialButtons = hasSocialAuth && (hasGoogle || hasApple);
|
|
67
|
+
|
|
68
|
+
// Store social buttons translations in const to satisfy type checker (safe because we check hasSocialAuth first)
|
|
69
|
+
const socialButtonsTranslations = translations.socialButtons!;
|
|
70
|
+
|
|
71
|
+
// PERFORMANCE: Stable callbacks for social sign-in (wrap async handlers)
|
|
72
|
+
const handleGooglePress = useCallback(() => {
|
|
73
|
+
void onGoogleSignIn?.();
|
|
74
|
+
}, [onGoogleSignIn]);
|
|
75
|
+
|
|
76
|
+
const handleApplePress = useCallback(() => {
|
|
77
|
+
void onAppleSignIn?.();
|
|
78
|
+
}, [onAppleSignIn]);
|
|
79
|
+
|
|
36
80
|
return (
|
|
37
81
|
<ScreenLayout
|
|
38
82
|
scrollable
|
|
@@ -41,15 +85,38 @@ export const LoginScreen = memo<LoginScreenProps>(({ translations }) => {
|
|
|
41
85
|
contentContainerStyle={{ justifyContent: "center" }}
|
|
42
86
|
backgroundColor={tokens.colors.backgroundPrimary}
|
|
43
87
|
>
|
|
88
|
+
{/* Optional Logo/Illustration */}
|
|
89
|
+
{renderLogo && (
|
|
90
|
+
<View style={styles.logoContainer}>{renderLogo()}</View>
|
|
91
|
+
)}
|
|
92
|
+
|
|
44
93
|
<AuthHeader title={translations.title} subtitle={translations.subtitle} />
|
|
94
|
+
|
|
45
95
|
<AtomicCard variant="elevated" padding="lg">
|
|
46
96
|
<LoginForm
|
|
47
97
|
translations={translations.form}
|
|
48
98
|
onNavigateToRegister={handleNavigateToRegister}
|
|
49
99
|
/>
|
|
100
|
+
|
|
101
|
+
{/* Social Login Buttons */}
|
|
102
|
+
{showSocialButtons && (
|
|
103
|
+
<SocialLoginButtons
|
|
104
|
+
translations={socialButtonsTranslations}
|
|
105
|
+
enabledProviders={enabledProviders}
|
|
106
|
+
onGooglePress={hasGoogle ? handleGooglePress : undefined}
|
|
107
|
+
onApplePress={hasApple ? handleApplePress : undefined}
|
|
108
|
+
/>
|
|
109
|
+
)}
|
|
50
110
|
</AtomicCard>
|
|
51
111
|
</ScreenLayout>
|
|
52
112
|
);
|
|
53
113
|
});
|
|
54
114
|
|
|
55
115
|
LoginScreen.displayName = 'LoginScreen';
|
|
116
|
+
|
|
117
|
+
const styles = StyleSheet.create({
|
|
118
|
+
logoContainer: {
|
|
119
|
+
alignItems: "center",
|
|
120
|
+
marginBottom: 24,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Register Screen Component
|
|
3
|
-
* Registration form screen with navigation
|
|
3
|
+
* Registration form screen with navigation and social auth support
|
|
4
4
|
* PERFORMANCE: Memoized to prevent unnecessary re-renders
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { memo, useCallback } from "react";
|
|
7
|
+
import React, { memo, useCallback, useMemo } from "react";
|
|
8
|
+
import { View, StyleSheet } from "react-native";
|
|
8
9
|
import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
|
|
9
10
|
import { AtomicCard } from "@umituz/react-native-design-system/atoms";
|
|
10
11
|
import { useAppNavigation } from "@umituz/react-native-design-system/molecules";
|
|
11
12
|
import { ScreenLayout } from "@umituz/react-native-design-system/layouts";
|
|
12
13
|
import { useResponsive } from "@umituz/react-native-design-system/responsive";
|
|
14
|
+
import type { SocialAuthConfiguration } from "../hooks/useAuthBottomSheet";
|
|
15
|
+
import type { SocialAuthProvider } from "../../domain/value-objects/AuthConfig";
|
|
13
16
|
import { AuthHeader } from "../components/AuthHeader";
|
|
14
17
|
import { RegisterForm, type RegisterFormTranslations } from "../components/RegisterForm";
|
|
18
|
+
import { SocialLoginButtons, type SocialLoginButtonsTranslations } from "../components/SocialLoginButtons";
|
|
15
19
|
|
|
16
20
|
export interface RegisterScreenTranslations {
|
|
17
21
|
title: string;
|
|
18
22
|
subtitle?: string;
|
|
19
23
|
form: RegisterFormTranslations;
|
|
24
|
+
socialButtons?: SocialLoginButtonsTranslations;
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export interface RegisterScreenProps {
|
|
@@ -25,9 +30,23 @@ export interface RegisterScreenProps {
|
|
|
25
30
|
privacyUrl?: string;
|
|
26
31
|
onTermsPress?: () => void;
|
|
27
32
|
onPrivacyPress?: () => void;
|
|
33
|
+
socialConfig?: SocialAuthConfiguration;
|
|
34
|
+
onGoogleSignIn?: () => Promise<void>;
|
|
35
|
+
onAppleSignIn?: () => Promise<void>;
|
|
36
|
+
renderLogo?: () => React.ReactNode;
|
|
28
37
|
}
|
|
29
38
|
|
|
30
|
-
export const RegisterScreen = memo<RegisterScreenProps>(({
|
|
39
|
+
export const RegisterScreen = memo<RegisterScreenProps>(({
|
|
40
|
+
translations,
|
|
41
|
+
termsUrl,
|
|
42
|
+
privacyUrl,
|
|
43
|
+
onTermsPress,
|
|
44
|
+
onPrivacyPress,
|
|
45
|
+
socialConfig,
|
|
46
|
+
onGoogleSignIn,
|
|
47
|
+
onAppleSignIn,
|
|
48
|
+
renderLogo,
|
|
49
|
+
}) => {
|
|
31
50
|
const navigation = useAppNavigation();
|
|
32
51
|
const tokens = useAppDesignTokens();
|
|
33
52
|
const responsive = useResponsive();
|
|
@@ -37,6 +56,35 @@ export const RegisterScreen = memo<RegisterScreenProps>(({ translations, termsUr
|
|
|
37
56
|
navigation.navigate("Login");
|
|
38
57
|
}, [navigation]);
|
|
39
58
|
|
|
59
|
+
// Determine enabled social providers
|
|
60
|
+
const enabledProviders = useMemo<SocialAuthProvider[]>(() => {
|
|
61
|
+
if (!socialConfig) return [];
|
|
62
|
+
const providers: SocialAuthProvider[] = [];
|
|
63
|
+
// For Google, check if config exists
|
|
64
|
+
if (socialConfig.google) providers.push("google");
|
|
65
|
+
// For Apple, check if enabled flag is true
|
|
66
|
+
if (socialConfig.apple?.enabled) providers.push("apple");
|
|
67
|
+
return providers;
|
|
68
|
+
}, [socialConfig]);
|
|
69
|
+
|
|
70
|
+
const hasSocialAuth = enabledProviders.length > 0 && translations.socialButtons;
|
|
71
|
+
// Check if required handlers exist for enabled providers (only need handler if provider is enabled)
|
|
72
|
+
const hasGoogle = enabledProviders.includes("google") && onGoogleSignIn;
|
|
73
|
+
const hasApple = enabledProviders.includes("apple") && onAppleSignIn;
|
|
74
|
+
const showSocialButtons = hasSocialAuth && (hasGoogle || hasApple);
|
|
75
|
+
|
|
76
|
+
// Store social buttons translations in const to satisfy type checker (safe because we check hasSocialAuth first)
|
|
77
|
+
const socialButtonsTranslations = translations.socialButtons!;
|
|
78
|
+
|
|
79
|
+
// PERFORMANCE: Stable callbacks for social sign-in (wrap async handlers)
|
|
80
|
+
const handleGooglePress = useCallback(() => {
|
|
81
|
+
void onGoogleSignIn?.();
|
|
82
|
+
}, [onGoogleSignIn]);
|
|
83
|
+
|
|
84
|
+
const handleApplePress = useCallback(() => {
|
|
85
|
+
void onAppleSignIn?.();
|
|
86
|
+
}, [onAppleSignIn]);
|
|
87
|
+
|
|
40
88
|
return (
|
|
41
89
|
<ScreenLayout
|
|
42
90
|
scrollable
|
|
@@ -45,7 +93,13 @@ export const RegisterScreen = memo<RegisterScreenProps>(({ translations, termsUr
|
|
|
45
93
|
contentContainerStyle={{ justifyContent: "center" }}
|
|
46
94
|
backgroundColor={tokens.colors.backgroundPrimary}
|
|
47
95
|
>
|
|
96
|
+
{/* Optional Logo/Illustration */}
|
|
97
|
+
{renderLogo && (
|
|
98
|
+
<View style={styles.logoContainer}>{renderLogo()}</View>
|
|
99
|
+
)}
|
|
100
|
+
|
|
48
101
|
<AuthHeader title={translations.title} subtitle={translations.subtitle} />
|
|
102
|
+
|
|
49
103
|
<AtomicCard variant="elevated" padding="lg">
|
|
50
104
|
<RegisterForm
|
|
51
105
|
translations={translations.form}
|
|
@@ -55,9 +109,26 @@ export const RegisterScreen = memo<RegisterScreenProps>(({ translations, termsUr
|
|
|
55
109
|
onTermsPress={onTermsPress}
|
|
56
110
|
onPrivacyPress={onPrivacyPress}
|
|
57
111
|
/>
|
|
112
|
+
|
|
113
|
+
{/* Social Login Buttons */}
|
|
114
|
+
{showSocialButtons && (
|
|
115
|
+
<SocialLoginButtons
|
|
116
|
+
translations={socialButtonsTranslations}
|
|
117
|
+
enabledProviders={enabledProviders}
|
|
118
|
+
onGooglePress={hasGoogle ? handleGooglePress : undefined}
|
|
119
|
+
onApplePress={hasApple ? handleApplePress : undefined}
|
|
120
|
+
/>
|
|
121
|
+
)}
|
|
58
122
|
</AtomicCard>
|
|
59
123
|
</ScreenLayout>
|
|
60
124
|
);
|
|
61
125
|
});
|
|
62
126
|
|
|
63
127
|
RegisterScreen.displayName = 'RegisterScreen';
|
|
128
|
+
|
|
129
|
+
const styles = StyleSheet.create({
|
|
130
|
+
logoContainer: {
|
|
131
|
+
alignItems: "center",
|
|
132
|
+
marginBottom: 24,
|
|
133
|
+
},
|
|
134
|
+
});
|