@fadyshawky/react-native-magic 1.0.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +7 -0
- package/package.json +1 -1
- package/template/App.tsx +30 -9
- package/template/package-lock.json +181 -123
- package/template/package.json +2 -0
- package/template/src/common/ImageResources.g.ts +3 -5
- package/template/src/common/components/Background.tsx +66 -28
- package/template/src/common/components/Cards.tsx +116 -0
- package/template/src/common/components/Container.tsx +145 -0
- package/template/src/common/components/FlatListWrapper.tsx +1 -0
- package/template/src/common/components/ImageCropPickerButton.tsx +1 -1
- package/template/src/common/components/OTPInput.tsx +107 -0
- package/template/src/common/components/PhotoTakingButton.tsx +1 -4
- package/template/src/common/components/PrimaryButton.tsx +171 -157
- package/template/src/common/components/RTLAwareText.tsx +42 -0
- package/template/src/common/components/RTLAwareView.tsx +179 -0
- package/template/src/common/components/RadioButton.tsx +1 -3
- package/template/src/common/components/RadioIcon.tsx +1 -2
- package/template/src/common/components/SearchBar.tsx +179 -0
- package/template/src/common/components/Separator.tsx +7 -4
- package/template/src/common/components/TouchablePlatform.tsx +1 -3
- package/template/src/common/components/TryAgain.tsx +3 -3
- package/template/src/common/helpers/inAppReviewHelper.ts +0 -1
- package/template/src/common/helpers/stringsHelpers.ts +10 -0
- package/template/src/common/hooks/useFlatListActions.ts +1 -1
- package/template/src/common/localization/LocalizationProvider.tsx +152 -0
- package/template/src/common/localization/README.md +488 -0
- package/template/src/common/localization/localization.ts +12 -0
- package/template/src/common/localization/translations/profileLocalization.ts +24 -0
- package/template/src/common/validations/errorValidations.ts +1 -6
- package/template/src/common/validations/examples/TextInputWithValidation.tsx +229 -0
- package/template/src/common/validations/index.ts +28 -0
- package/template/src/common/validations/regex.js +83 -0
- package/template/src/common/validations/regexValidator.ts +240 -0
- package/template/src/common/validations/validationConstants.ts +2 -2
- package/template/src/core/api/errorHandler.ts +39 -0
- package/template/src/core/api/responseHandlers.ts +1 -26
- package/template/src/core/api/serverHeaders.ts +13 -23
- package/template/src/core/store/app/appSlice.ts +1 -2
- package/template/src/core/theme/ThemeProvider.tsx +63 -0
- package/template/src/core/theme/colors.ts +31 -42
- package/template/src/core/theme/commonConsts.ts +1 -1
- package/template/src/core/theme/commonStyles.ts +267 -210
- package/template/src/core/theme/fonts.ts +17 -1
- package/template/src/core/theme/scaling.ts +101 -0
- package/template/src/core/theme/themes.ts +214 -0
- package/template/src/core/theme/types.ts +51 -0
- package/template/src/navigation/AuthStack.tsx +25 -30
- package/template/src/navigation/HeaderComponents.tsx +18 -58
- package/template/src/navigation/MainNavigation.tsx +5 -6
- package/template/src/navigation/MainStack.tsx +3 -28
- package/template/src/navigation/RootNavigation.tsx +1 -7
- package/template/src/navigation/TabBar.tsx +2 -2
- package/template/src/navigation/TopTabBar.tsx +1 -1
- package/template/src/screens/Login/Login.tsx +3 -3
- package/template/src/screens/home/components/CarouselSection.tsx +7 -8
- package/template/src/screens/home/components/FeaturedCarousel.tsx +5 -6
- package/template/src/screens/registration/RegistrationScreen.tsx +2 -2
- package/template/src/screens/resetPassword/ForgotPasswordScreen.tsx +2 -2
- package/template/src/utils/stringBuilder.js +25 -0
package/template/package.json
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"test": "jest"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
+
"@d11/react-native-fast-image": "^8.9.2",
|
|
22
23
|
"@react-native-async-storage/async-storage": "^2.1.0",
|
|
23
24
|
"@react-native-camera-roll/camera-roll": "^7.9.0",
|
|
24
25
|
"@react-native-community/datetimepicker": "^8.2.0",
|
|
@@ -66,6 +67,7 @@
|
|
|
66
67
|
"react-native-permissions": "^5.2.1",
|
|
67
68
|
"react-native-reanimated": "^3.16.6",
|
|
68
69
|
"react-native-reanimated-carousel": "^3.5.1",
|
|
70
|
+
"react-native-restart": "^0.0.27",
|
|
69
71
|
"react-native-safe-area-context": "^5.0.0",
|
|
70
72
|
"react-native-screens": "^4.4.0",
|
|
71
73
|
"react-native-sfsymbols": "^1.2.2",
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
/* tslint:disable */
|
|
3
|
-
import {ImageURISource} from
|
|
3
|
+
import {ImageURISource} from 'react-native';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* This file is auto-generated by react-native-image-resource-generator
|
|
7
7
|
* !!! DO NOT EDIT !!!
|
|
8
8
|
* For more information check the documentation:
|
|
9
9
|
* https://github.com/svbutko/react-native-image-resource-generator
|
|
10
|
-
*/
|
|
10
|
+
*/
|
|
11
11
|
|
|
12
|
-
export class ImageResources {
|
|
13
|
-
|
|
14
|
-
}
|
|
12
|
+
export class ImageResources {}
|
|
@@ -1,33 +1,71 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {ImageBackground, StyleSheet, ViewStyle} from 'react-native';
|
|
3
|
-
import {
|
|
1
|
+
import React, {FC, memo} from 'react';
|
|
2
|
+
import {ImageBackground, StyleSheet, View, ViewStyle} from 'react-native';
|
|
3
|
+
import {useTheme} from '../../core/theme/ThemeProvider';
|
|
4
|
+
import {ImageResources} from '../ImageResources.g';
|
|
5
|
+
import {Container} from './Container';
|
|
6
|
+
import {KeyboardAwareScrollViewProps} from 'react-native-keyboard-aware-scroll-view';
|
|
4
7
|
|
|
5
|
-
interface
|
|
8
|
+
interface BackgroundProps
|
|
9
|
+
extends Omit<KeyboardAwareScrollViewProps, 'contentContainerStyle'> {
|
|
6
10
|
children: React.ReactNode;
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
useSafeArea?: boolean;
|
|
12
|
+
style?: ViewStyle;
|
|
13
|
+
contentContainerStyle?: ViewStyle;
|
|
14
|
+
withoutPadding?: boolean;
|
|
15
|
+
withoutScroll?: boolean;
|
|
16
|
+
withoutBackgroundImage?: boolean;
|
|
9
17
|
}
|
|
10
18
|
|
|
11
|
-
export const Background = (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
export const Background: FC<BackgroundProps> = memo(
|
|
20
|
+
({
|
|
21
|
+
children,
|
|
22
|
+
useSafeArea = true,
|
|
23
|
+
style,
|
|
24
|
+
contentContainerStyle,
|
|
25
|
+
withoutPadding = false,
|
|
26
|
+
withoutScroll = false,
|
|
27
|
+
withoutBackgroundImage = false,
|
|
28
|
+
...scrollViewProps
|
|
29
|
+
}) => {
|
|
30
|
+
const {theme} = useTheme();
|
|
23
31
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const content = (
|
|
33
|
+
<Container
|
|
34
|
+
useSafeArea={useSafeArea}
|
|
35
|
+
style={style}
|
|
36
|
+
contentContainerStyle={contentContainerStyle}
|
|
37
|
+
withoutPadding={withoutPadding}
|
|
38
|
+
withoutScroll={withoutScroll}
|
|
39
|
+
{...scrollViewProps}>
|
|
40
|
+
{children}
|
|
41
|
+
</Container>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
if (withoutBackgroundImage) {
|
|
45
|
+
return (
|
|
46
|
+
<View
|
|
47
|
+
style={[
|
|
48
|
+
styles.container,
|
|
49
|
+
{backgroundColor: theme.colors.background},
|
|
50
|
+
]}>
|
|
51
|
+
{content}
|
|
52
|
+
</View>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<View
|
|
58
|
+
style={[styles.container, {backgroundColor: theme.colors.background}]}>
|
|
59
|
+
<ImageBackground source={0} style={styles.container}>
|
|
60
|
+
{content}
|
|
61
|
+
</ImageBackground>
|
|
62
|
+
</View>
|
|
63
|
+
);
|
|
64
|
+
},
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const styles = StyleSheet.create({
|
|
68
|
+
container: {
|
|
69
|
+
flex: 1,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Image,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
Text,
|
|
6
|
+
TouchableOpacity,
|
|
7
|
+
View,
|
|
8
|
+
ViewStyle,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import {CommonSizes} from '../../core/theme/commonSizes';
|
|
11
|
+
import {createThemedStyles} from '../../core/theme/commonStyles';
|
|
12
|
+
import {scaleHeight, scaleWidth} from '../../core/theme/scaling';
|
|
13
|
+
import {useTheme} from '../../core/theme/ThemeProvider';
|
|
14
|
+
import FastImage from '@d11/react-native-fast-image';
|
|
15
|
+
|
|
16
|
+
interface CardProps {
|
|
17
|
+
icon: {uri: string};
|
|
18
|
+
title: string;
|
|
19
|
+
onPress?: () => void;
|
|
20
|
+
marginRight?: number;
|
|
21
|
+
cardStyle?: ViewStyle;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const Card = ({
|
|
25
|
+
icon,
|
|
26
|
+
title,
|
|
27
|
+
onPress,
|
|
28
|
+
marginRight,
|
|
29
|
+
cardStyle,
|
|
30
|
+
}: CardProps): JSX.Element => {
|
|
31
|
+
const {theme} = useTheme();
|
|
32
|
+
return (
|
|
33
|
+
<TouchableOpacity
|
|
34
|
+
style={[
|
|
35
|
+
styles.card,
|
|
36
|
+
{backgroundColor: theme.colors.surface},
|
|
37
|
+
createThemedStyles(theme).dropShadow,
|
|
38
|
+
{marginRight: marginRight},
|
|
39
|
+
{overflow: 'hidden'},
|
|
40
|
+
cardStyle,
|
|
41
|
+
]}
|
|
42
|
+
onPress={() => {
|
|
43
|
+
onPress?.();
|
|
44
|
+
}}>
|
|
45
|
+
<View style={styles.iconContainer}>
|
|
46
|
+
{icon && icon.uri && (
|
|
47
|
+
<FastImage
|
|
48
|
+
source={{uri: icon.uri, cache: FastImage.cacheControl.immutable}}
|
|
49
|
+
style={{
|
|
50
|
+
width: '100%',
|
|
51
|
+
height: '100%',
|
|
52
|
+
}}
|
|
53
|
+
resizeMode={FastImage.resizeMode.contain}
|
|
54
|
+
/>
|
|
55
|
+
)}
|
|
56
|
+
</View>
|
|
57
|
+
<Text style={[theme.text.cards, {textAlign: 'center'}]}>{title}</Text>
|
|
58
|
+
</TouchableOpacity>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const styles = StyleSheet.create({
|
|
63
|
+
card: {
|
|
64
|
+
padding: CommonSizes.spacing.medium,
|
|
65
|
+
borderRadius: CommonSizes.borderRadius.large,
|
|
66
|
+
alignItems: 'center',
|
|
67
|
+
justifyContent: 'flex-start',
|
|
68
|
+
gap: scaleHeight(10),
|
|
69
|
+
width: scaleWidth(187),
|
|
70
|
+
height: scaleHeight(280),
|
|
71
|
+
},
|
|
72
|
+
blurContainer: {
|
|
73
|
+
flex: 1,
|
|
74
|
+
padding: CommonSizes.spacing.medium,
|
|
75
|
+
alignItems: 'center',
|
|
76
|
+
justifyContent: 'center',
|
|
77
|
+
},
|
|
78
|
+
iconContainer: {
|
|
79
|
+
width: '100%',
|
|
80
|
+
height: scaleHeight(100),
|
|
81
|
+
},
|
|
82
|
+
title: {
|
|
83
|
+
fontSize: CommonSizes.fontSize.body2,
|
|
84
|
+
textAlign: 'center',
|
|
85
|
+
marginBottom: CommonSizes.spacing.small,
|
|
86
|
+
},
|
|
87
|
+
dotsContainer: {
|
|
88
|
+
flexDirection: 'row',
|
|
89
|
+
gap: 4,
|
|
90
|
+
},
|
|
91
|
+
dot: {
|
|
92
|
+
width: 4,
|
|
93
|
+
height: 4,
|
|
94
|
+
borderRadius: 2,
|
|
95
|
+
},
|
|
96
|
+
whiteDropShadow: {
|
|
97
|
+
// iOS shadow
|
|
98
|
+
shadowColor: '#FFF',
|
|
99
|
+
shadowOffset: {
|
|
100
|
+
width: 0,
|
|
101
|
+
height: 4,
|
|
102
|
+
},
|
|
103
|
+
shadowOpacity: 0.25,
|
|
104
|
+
shadowRadius: 8,
|
|
105
|
+
// Android shadow
|
|
106
|
+
elevation: 5,
|
|
107
|
+
// Add a very subtle border to enhance the white shadow effect
|
|
108
|
+
borderWidth: 0.5,
|
|
109
|
+
borderColor: 'rgba(255, 255, 255, 0.1)',
|
|
110
|
+
},
|
|
111
|
+
favoriteContainer: {
|
|
112
|
+
position: 'absolute',
|
|
113
|
+
top: scaleHeight(17),
|
|
114
|
+
left: scaleWidth(12),
|
|
115
|
+
},
|
|
116
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import React, {forwardRef} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
StyleSheet,
|
|
4
|
+
ViewStyle,
|
|
5
|
+
Platform,
|
|
6
|
+
KeyboardAvoidingView,
|
|
7
|
+
ScrollView,
|
|
8
|
+
View,
|
|
9
|
+
ImageBackground,
|
|
10
|
+
ImageSourcePropType,
|
|
11
|
+
} from 'react-native';
|
|
12
|
+
import {
|
|
13
|
+
KeyboardAwareScrollView,
|
|
14
|
+
KeyboardAwareScrollViewProps,
|
|
15
|
+
} from 'react-native-keyboard-aware-scroll-view';
|
|
16
|
+
import {useTheme} from '../../core/theme/ThemeProvider';
|
|
17
|
+
import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
18
|
+
import {ImageResources} from '../ImageResources.g';
|
|
19
|
+
|
|
20
|
+
interface ContainerProps extends Partial<KeyboardAwareScrollViewProps> {
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
useSafeArea?: boolean;
|
|
23
|
+
style?: ViewStyle;
|
|
24
|
+
contentContainerStyle?: ViewStyle;
|
|
25
|
+
withoutPadding?: boolean;
|
|
26
|
+
withoutScroll?: boolean;
|
|
27
|
+
backgroundColor?: string;
|
|
28
|
+
withoutBackgroundImage?: boolean;
|
|
29
|
+
backgroundImage?: ImageSourcePropType;
|
|
30
|
+
extendedBackground?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const Container = forwardRef<KeyboardAwareScrollView, ContainerProps>(
|
|
34
|
+
(
|
|
35
|
+
{
|
|
36
|
+
children,
|
|
37
|
+
useSafeArea = true,
|
|
38
|
+
style,
|
|
39
|
+
contentContainerStyle,
|
|
40
|
+
withoutPadding = false,
|
|
41
|
+
withoutScroll = false,
|
|
42
|
+
backgroundColor,
|
|
43
|
+
withoutBackgroundImage = false,
|
|
44
|
+
backgroundImage = 0,
|
|
45
|
+
extendedBackground = false,
|
|
46
|
+
...scrollViewProps
|
|
47
|
+
},
|
|
48
|
+
ref,
|
|
49
|
+
) => {
|
|
50
|
+
const {theme} = useTheme();
|
|
51
|
+
const insets = useSafeAreaInsets();
|
|
52
|
+
const Wrapper = useSafeArea ? SafeAreaView : View;
|
|
53
|
+
const bgColor = backgroundColor || theme.colors.background;
|
|
54
|
+
|
|
55
|
+
const content = (
|
|
56
|
+
<Wrapper
|
|
57
|
+
style={[
|
|
58
|
+
styles.container,
|
|
59
|
+
!withoutPadding && styles.padding,
|
|
60
|
+
style,
|
|
61
|
+
extendedBackground && {
|
|
62
|
+
marginTop: -insets.top,
|
|
63
|
+
paddingTop: insets.top,
|
|
64
|
+
},
|
|
65
|
+
]}>
|
|
66
|
+
{children}
|
|
67
|
+
</Wrapper>
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const wrappedContent = withoutBackgroundImage ? (
|
|
71
|
+
<View style={[styles.container, {backgroundColor: bgColor}]}>
|
|
72
|
+
{content}
|
|
73
|
+
</View>
|
|
74
|
+
) : (
|
|
75
|
+
<ImageBackground
|
|
76
|
+
source={backgroundImage}
|
|
77
|
+
style={[
|
|
78
|
+
styles.container,
|
|
79
|
+
extendedBackground && {
|
|
80
|
+
marginTop: -insets.top,
|
|
81
|
+
},
|
|
82
|
+
]}
|
|
83
|
+
resizeMode="cover">
|
|
84
|
+
{content}
|
|
85
|
+
</ImageBackground>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if (withoutScroll) {
|
|
89
|
+
return (
|
|
90
|
+
<KeyboardAvoidingView
|
|
91
|
+
style={[
|
|
92
|
+
styles.container,
|
|
93
|
+
{backgroundColor: bgColor},
|
|
94
|
+
extendedBackground && {
|
|
95
|
+
marginTop: -insets.top,
|
|
96
|
+
},
|
|
97
|
+
]}
|
|
98
|
+
behavior={undefined}
|
|
99
|
+
enabled>
|
|
100
|
+
{wrappedContent}
|
|
101
|
+
</KeyboardAvoidingView>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<KeyboardAwareScrollView
|
|
107
|
+
ref={ref}
|
|
108
|
+
style={[
|
|
109
|
+
styles.container,
|
|
110
|
+
{backgroundColor: bgColor},
|
|
111
|
+
extendedBackground && {
|
|
112
|
+
marginTop: -insets.top,
|
|
113
|
+
},
|
|
114
|
+
]}
|
|
115
|
+
contentContainerStyle={[
|
|
116
|
+
styles.contentContainer,
|
|
117
|
+
!withoutPadding && styles.padding,
|
|
118
|
+
contentContainerStyle,
|
|
119
|
+
]}
|
|
120
|
+
keyboardShouldPersistTaps="handled"
|
|
121
|
+
showsVerticalScrollIndicator={false}
|
|
122
|
+
enableOnAndroid
|
|
123
|
+
enableResetScrollToCoords={false}
|
|
124
|
+
extraScrollHeight={20}
|
|
125
|
+
keyboardOpeningTime={0}
|
|
126
|
+
keyboardDismissMode="on-drag"
|
|
127
|
+
enableAutomaticScroll={true}
|
|
128
|
+
{...scrollViewProps}>
|
|
129
|
+
{wrappedContent}
|
|
130
|
+
</KeyboardAwareScrollView>
|
|
131
|
+
);
|
|
132
|
+
},
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const styles = StyleSheet.create({
|
|
136
|
+
container: {
|
|
137
|
+
flex: 1,
|
|
138
|
+
},
|
|
139
|
+
contentContainer: {
|
|
140
|
+
flexGrow: 1,
|
|
141
|
+
},
|
|
142
|
+
padding: {
|
|
143
|
+
padding: 16, // Using a fixed value here as theme isn't available in StyleSheet
|
|
144
|
+
},
|
|
145
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React, {useRef, useState} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
NativeSyntheticEvent,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
TextInput,
|
|
6
|
+
TextInputKeyPressEventData,
|
|
7
|
+
ViewStyle,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import {useTheme} from '../../core/theme/ThemeProvider';
|
|
10
|
+
import {CommonSizes} from '../../core/theme/commonSizes';
|
|
11
|
+
import {scaleWidth} from '../../core/theme/scaling';
|
|
12
|
+
import {PrimaryTextInput} from './PrimaryTextInput';
|
|
13
|
+
import {RTLAwareView} from './RTLAwareView';
|
|
14
|
+
|
|
15
|
+
interface OTPInputProps {
|
|
16
|
+
value: string;
|
|
17
|
+
onChange: (value: string) => void;
|
|
18
|
+
error?: string | null;
|
|
19
|
+
style?: ViewStyle;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const OTPInput: React.FC<OTPInputProps> = ({
|
|
23
|
+
value,
|
|
24
|
+
onChange,
|
|
25
|
+
error,
|
|
26
|
+
style,
|
|
27
|
+
}) => {
|
|
28
|
+
const {theme} = useTheme();
|
|
29
|
+
const inputRefs = useRef<Array<TextInput | null>>([]);
|
|
30
|
+
const [focused, setFocused] = useState<number>(-1);
|
|
31
|
+
|
|
32
|
+
const handleChange = (text: string, index: number) => {
|
|
33
|
+
const newValue = value.split('');
|
|
34
|
+
newValue[index] = text;
|
|
35
|
+
const finalValue = newValue.join('');
|
|
36
|
+
onChange(finalValue);
|
|
37
|
+
|
|
38
|
+
if (text.length > 0 && index < 5) {
|
|
39
|
+
inputRefs.current[index + 1]?.focus();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const handleKeyPress = (
|
|
44
|
+
e: NativeSyntheticEvent<TextInputKeyPressEventData>,
|
|
45
|
+
index: number,
|
|
46
|
+
) => {
|
|
47
|
+
if (e.nativeEvent.key === 'Backspace' && index > 0 && !value[index]) {
|
|
48
|
+
inputRefs.current[index - 1]?.focus();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handleFocus = (index: number) => {
|
|
53
|
+
setFocused(index);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const handleBlur = () => {
|
|
57
|
+
setFocused(-1);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<RTLAwareView style={{...styles.container, ...style}}>
|
|
62
|
+
{[0, 1, 2, 3, 4, 5].map(index => (
|
|
63
|
+
<PrimaryTextInput
|
|
64
|
+
width={scaleWidth(78)}
|
|
65
|
+
key={index}
|
|
66
|
+
inputRef={ref => (inputRefs.current[index] = ref)}
|
|
67
|
+
style={[
|
|
68
|
+
styles.input,
|
|
69
|
+
{
|
|
70
|
+
borderColor: error
|
|
71
|
+
? theme.colors.mutedLavender
|
|
72
|
+
: focused === index
|
|
73
|
+
? theme.colors.indigoBlue
|
|
74
|
+
: theme.colors.mutedLavender30,
|
|
75
|
+
backgroundColor: theme.colors.backgroundOpacity,
|
|
76
|
+
},
|
|
77
|
+
]}
|
|
78
|
+
maxLength={1}
|
|
79
|
+
keyboardType="number-pad"
|
|
80
|
+
value={value[index] || ''}
|
|
81
|
+
onChangeText={text => handleChange(text, index)}
|
|
82
|
+
onKeyPress={e => handleKeyPress(e, index)}
|
|
83
|
+
onFocus={() => handleFocus(index)}
|
|
84
|
+
onBlur={handleBlur}
|
|
85
|
+
selectTextOnFocus
|
|
86
|
+
/>
|
|
87
|
+
))}
|
|
88
|
+
</RTLAwareView>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const styles = StyleSheet.create({
|
|
93
|
+
container: {
|
|
94
|
+
flexDirection: 'row',
|
|
95
|
+
justifyContent: 'space-between',
|
|
96
|
+
width: '100%',
|
|
97
|
+
gap: CommonSizes.spacing.small,
|
|
98
|
+
paddingHorizontal: CommonSizes.spacing.large,
|
|
99
|
+
},
|
|
100
|
+
input: {
|
|
101
|
+
flex: 1,
|
|
102
|
+
height: CommonSizes.spacing.xxl,
|
|
103
|
+
borderWidth: 1,
|
|
104
|
+
borderRadius: CommonSizes.borderRadius.medium,
|
|
105
|
+
textAlign: 'center',
|
|
106
|
+
},
|
|
107
|
+
});
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
ViewStyle,
|
|
10
10
|
} from 'react-native';
|
|
11
11
|
import {Image as CropperImage} from 'react-native-image-crop-picker';
|
|
12
|
-
import {Colors} from '../../core/theme/colors';
|
|
13
12
|
import {CommonSizes} from '../../core/theme/commonSizes';
|
|
14
13
|
|
|
15
14
|
interface IProps {
|
|
@@ -35,7 +34,7 @@ export const PhotoTakingButton: FC<IProps> = memo(
|
|
|
35
34
|
return (
|
|
36
35
|
<TouchableOpacity
|
|
37
36
|
style={[styles.button, style]}
|
|
38
|
-
|
|
37
|
+
onPressIn={onPress}
|
|
39
38
|
disabled={disabled}>
|
|
40
39
|
<BackgroundComponent image={backgroundImage} style={imageStyle}>
|
|
41
40
|
<Image style={[styles.icon, iconStyle]} source={icon!} />
|
|
@@ -76,7 +75,6 @@ const styles = StyleSheet.create({
|
|
|
76
75
|
justifyContent: 'center',
|
|
77
76
|
borderRadius: CommonSizes.borderRadius.small,
|
|
78
77
|
borderWidth: 1,
|
|
79
|
-
borderColor: Colors.gray,
|
|
80
78
|
} as ViewStyle,
|
|
81
79
|
image: {
|
|
82
80
|
height: 120,
|
|
@@ -91,7 +89,6 @@ const styles = StyleSheet.create({
|
|
|
91
89
|
width: 32,
|
|
92
90
|
height: 32,
|
|
93
91
|
resizeMode: 'contain',
|
|
94
|
-
tintColor: Colors.black,
|
|
95
92
|
opacity: 0.8,
|
|
96
93
|
} as ImageStyle,
|
|
97
94
|
});
|