@fadyshawky/react-native-magic 1.0.8 → 1.0.9
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 +170 -123
- package/template/package.json +1 -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
|
@@ -16,11 +16,13 @@ import {
|
|
|
16
16
|
IIconPlatformProps,
|
|
17
17
|
TouchablePlatformProps,
|
|
18
18
|
} from '../../../types';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
19
|
+
import {useTheme} from '../../core/theme/ThemeProvider';
|
|
20
|
+
import {BorderRadius, Spacing} from '../../core/theme/commonSizes';
|
|
21
|
+
import {createThemedStyles} from '../../core/theme/commonStyles';
|
|
22
|
+
import {Theme} from '../../core/theme/types';
|
|
22
23
|
import {IconPlatform} from './IconPlatform';
|
|
23
24
|
import {TouchablePlatform} from './TouchablePlatform';
|
|
25
|
+
import {scaleHeight, scaleSpacing} from '../../core/theme/scaling';
|
|
24
26
|
|
|
25
27
|
interface IProps extends TouchablePlatformProps {
|
|
26
28
|
label: string;
|
|
@@ -46,16 +48,17 @@ export const PrimaryButton: FC<IProps> = memo(
|
|
|
46
48
|
platformIconProps,
|
|
47
49
|
...props
|
|
48
50
|
}) => {
|
|
51
|
+
const {theme} = useTheme();
|
|
49
52
|
const styles = useMemo(() => {
|
|
50
|
-
return getStyles(type, rounded, props.disabled);
|
|
51
|
-
}, [type, rounded, props.disabled]);
|
|
53
|
+
return getStyles(theme, type, rounded, props.disabled);
|
|
54
|
+
}, [theme, type, rounded, props.disabled]);
|
|
52
55
|
|
|
53
56
|
const content = useMemo(() => {
|
|
54
57
|
if (isLoading) {
|
|
55
58
|
return (
|
|
56
59
|
<ActivityIndicator
|
|
57
60
|
animating={true}
|
|
58
|
-
color={
|
|
61
|
+
color={theme.colors.backgroundOpacity}
|
|
59
62
|
size={'small'}
|
|
60
63
|
/>
|
|
61
64
|
);
|
|
@@ -82,12 +85,13 @@ export const PrimaryButton: FC<IProps> = memo(
|
|
|
82
85
|
platformIconProps,
|
|
83
86
|
styles.icon,
|
|
84
87
|
styles.label,
|
|
88
|
+
theme,
|
|
85
89
|
]);
|
|
86
90
|
|
|
87
91
|
return (
|
|
88
92
|
<TouchablePlatform
|
|
89
93
|
style={[styles.button, style] as ViewStyle[]}
|
|
90
|
-
highlightColor={
|
|
94
|
+
highlightColor={theme.colors.mutedLavender30}
|
|
91
95
|
{...props}>
|
|
92
96
|
{content}
|
|
93
97
|
</TouchablePlatform>
|
|
@@ -95,8 +99,6 @@ export const PrimaryButton: FC<IProps> = memo(
|
|
|
95
99
|
},
|
|
96
100
|
);
|
|
97
101
|
|
|
98
|
-
const activityIndicatorColor = Colors.gray_disabled;
|
|
99
|
-
|
|
100
102
|
const ButtonIcon: FC<Pick<IProps, 'icon' | 'iconStyle' | 'platformIconProps'>> =
|
|
101
103
|
memo(props => {
|
|
102
104
|
if (props.icon != null) {
|
|
@@ -109,59 +111,68 @@ const ButtonIcon: FC<Pick<IProps, 'icon' | 'iconStyle' | 'platformIconProps'>> =
|
|
|
109
111
|
});
|
|
110
112
|
|
|
111
113
|
function getStyles(
|
|
114
|
+
theme: Theme,
|
|
112
115
|
type: ButtonType,
|
|
113
116
|
rounded?: boolean,
|
|
114
117
|
disabled?: boolean | null,
|
|
115
118
|
): IStyles {
|
|
119
|
+
const baseStyles = createButtonStyles(theme);
|
|
120
|
+
|
|
116
121
|
switch (type) {
|
|
117
122
|
case ButtonType.solid:
|
|
118
123
|
return mergeStylesWithDisabled(
|
|
119
|
-
|
|
124
|
+
theme,
|
|
125
|
+
rounded ? createSmallSolidStyles(theme) : baseStyles.solid,
|
|
120
126
|
disabled,
|
|
121
127
|
);
|
|
122
128
|
case ButtonType.outline:
|
|
123
129
|
return mergeStylesWithDisabled(
|
|
124
|
-
|
|
130
|
+
theme,
|
|
131
|
+
rounded ? createSmallOutlineStyles(theme) : baseStyles.outline,
|
|
125
132
|
disabled,
|
|
126
133
|
true,
|
|
127
134
|
);
|
|
128
135
|
case ButtonType.outlineNegative:
|
|
129
136
|
return mergeStylesWithDisabled(
|
|
130
|
-
|
|
137
|
+
theme,
|
|
138
|
+
rounded ? createSmallOutlineStyles(theme) : baseStyles.outlineNegative,
|
|
131
139
|
disabled,
|
|
132
140
|
true,
|
|
133
141
|
);
|
|
134
142
|
case ButtonType.borderless:
|
|
135
|
-
return
|
|
143
|
+
return baseStyles.borderless;
|
|
136
144
|
default:
|
|
137
145
|
throw new Error('Unknown button type: ' + type);
|
|
138
146
|
}
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
function mergeStylesWithDisabled(
|
|
150
|
+
theme: Theme,
|
|
142
151
|
styles: IStyles,
|
|
143
152
|
disabled?: boolean | null,
|
|
144
153
|
outline?: boolean,
|
|
145
154
|
): IStyles {
|
|
146
|
-
return
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
if (!disabled) return styles;
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
...styles,
|
|
159
|
+
button: {
|
|
160
|
+
...styles.button,
|
|
161
|
+
backgroundColor: theme.colors.mutedLavender30,
|
|
162
|
+
borderColor: outline
|
|
163
|
+
? theme.colors.mutedLavender
|
|
164
|
+
: styles.button.borderColor,
|
|
165
|
+
elevation: 0,
|
|
166
|
+
} as ViewStyle,
|
|
167
|
+
icon: {
|
|
168
|
+
...styles.icon,
|
|
169
|
+
tintColor: theme.colors.mutedLavender,
|
|
170
|
+
} as ImageStyle,
|
|
171
|
+
label: {
|
|
172
|
+
...styles.label,
|
|
173
|
+
color: theme.colors.backgroundOpacity,
|
|
174
|
+
} as TextStyle,
|
|
175
|
+
};
|
|
165
176
|
}
|
|
166
177
|
|
|
167
178
|
interface IStyles {
|
|
@@ -170,136 +181,139 @@ interface IStyles {
|
|
|
170
181
|
label: TextStyle;
|
|
171
182
|
}
|
|
172
183
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const commonLabelStyle: TextStyle = {
|
|
184
|
-
...CommonStyles.h4_bold,
|
|
185
|
-
color: Colors.white,
|
|
186
|
-
textAlign: 'center',
|
|
187
|
-
textAlignVertical: 'center',
|
|
188
|
-
...Platform.select({
|
|
189
|
-
android: {
|
|
190
|
-
textTransform: 'uppercase',
|
|
191
|
-
} as TextStyle,
|
|
192
|
-
}),
|
|
193
|
-
};
|
|
184
|
+
function createButtonStyles(theme: Theme) {
|
|
185
|
+
const commonButtonStyle: ViewStyle = {
|
|
186
|
+
height: scaleHeight(97),
|
|
187
|
+
alignItems: 'center',
|
|
188
|
+
justifyContent: 'center',
|
|
189
|
+
borderRadius: 12,
|
|
190
|
+
flexDirection: 'row',
|
|
191
|
+
backgroundColor: 'transparent',
|
|
192
|
+
width: '100%',
|
|
193
|
+
};
|
|
194
194
|
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
195
|
+
const commonLabelStyle: TextStyle = {
|
|
196
|
+
...createThemedStyles(theme).h4_bold,
|
|
197
|
+
color: theme.colors.white,
|
|
198
|
+
textAlign: 'center',
|
|
199
|
+
textAlignVertical: 'center',
|
|
200
|
+
...Platform.select({
|
|
201
|
+
android: {
|
|
202
|
+
textTransform: 'uppercase',
|
|
203
|
+
} as TextStyle,
|
|
204
|
+
}),
|
|
205
|
+
};
|
|
202
206
|
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
} as TextStyle,
|
|
211
|
-
icon: {
|
|
212
|
-
...commonIcon,
|
|
213
|
-
tintColor: Colors.white,
|
|
214
|
-
},
|
|
215
|
-
});
|
|
207
|
+
const commonIcon: ImageStyle = {
|
|
208
|
+
width: 22,
|
|
209
|
+
height: 22,
|
|
210
|
+
marginHorizontal: scaleSpacing(12),
|
|
211
|
+
resizeMode: 'contain',
|
|
212
|
+
tintColor: theme.colors.indigoBlue,
|
|
213
|
+
};
|
|
216
214
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
tintColor: Colors.blue100,
|
|
230
|
-
} as ImageStyle,
|
|
231
|
-
});
|
|
215
|
+
return {
|
|
216
|
+
solid: StyleSheet.create({
|
|
217
|
+
button: {
|
|
218
|
+
...commonButtonStyle,
|
|
219
|
+
backgroundColor: theme.colors.indigoBlue,
|
|
220
|
+
} as ViewStyle,
|
|
221
|
+
label: theme.text.button,
|
|
222
|
+
icon: {
|
|
223
|
+
...commonIcon,
|
|
224
|
+
tintColor: theme.colors.white,
|
|
225
|
+
},
|
|
226
|
+
}),
|
|
232
227
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
...commonIcon,
|
|
245
|
-
tintColor: Colors.red,
|
|
246
|
-
} as ImageStyle,
|
|
247
|
-
});
|
|
228
|
+
outline: StyleSheet.create({
|
|
229
|
+
button: {
|
|
230
|
+
...commonButtonStyle,
|
|
231
|
+
borderColor: theme.colors.indigoBlue,
|
|
232
|
+
borderWidth: 2,
|
|
233
|
+
} as ViewStyle,
|
|
234
|
+
label: {
|
|
235
|
+
...theme.text.button,
|
|
236
|
+
} as TextStyle,
|
|
237
|
+
icon: commonIcon,
|
|
238
|
+
}),
|
|
248
239
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
tintColor: Colors.blue100,
|
|
264
|
-
} as ImageStyle,
|
|
265
|
-
});
|
|
240
|
+
outlineNegative: StyleSheet.create({
|
|
241
|
+
button: {
|
|
242
|
+
...commonButtonStyle,
|
|
243
|
+
borderColor: theme.colors.mutedLavender,
|
|
244
|
+
borderWidth: 2,
|
|
245
|
+
} as ViewStyle,
|
|
246
|
+
label: {
|
|
247
|
+
...theme.text.button,
|
|
248
|
+
} as TextStyle,
|
|
249
|
+
icon: {
|
|
250
|
+
...commonIcon,
|
|
251
|
+
tintColor: theme.colors.mutedLavender,
|
|
252
|
+
},
|
|
253
|
+
}),
|
|
266
254
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
255
|
+
borderless: StyleSheet.create({
|
|
256
|
+
button: {
|
|
257
|
+
...commonButtonStyle,
|
|
258
|
+
borderRadius: undefined,
|
|
259
|
+
width: undefined,
|
|
260
|
+
padding: undefined,
|
|
261
|
+
} as ViewStyle,
|
|
262
|
+
label: {
|
|
263
|
+
...theme.text.hyperlink,
|
|
264
|
+
} as TextStyle,
|
|
265
|
+
icon: commonIcon,
|
|
266
|
+
}),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
277
269
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
270
|
+
function createSmallSolidStyles(theme: Theme): IStyles {
|
|
271
|
+
const commonStyles = createThemedStyles(theme);
|
|
272
|
+
return StyleSheet.create({
|
|
273
|
+
button: {
|
|
274
|
+
padding: Spacing.medium,
|
|
275
|
+
alignItems: 'center',
|
|
276
|
+
justifyContent: 'center',
|
|
277
|
+
borderRadius: BorderRadius.extraLarge,
|
|
278
|
+
flexDirection: 'row',
|
|
279
|
+
backgroundColor: theme.colors.indigoBlue,
|
|
280
|
+
// width: 175,
|
|
281
|
+
} as ViewStyle,
|
|
282
|
+
label: {
|
|
283
|
+
...theme.text.button,
|
|
284
|
+
} as TextStyle,
|
|
285
|
+
icon: {
|
|
286
|
+
width: 22,
|
|
287
|
+
height: 22,
|
|
288
|
+
resizeMode: 'contain',
|
|
289
|
+
tintColor: theme.colors.white,
|
|
290
|
+
} as ImageStyle,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
290
293
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
294
|
+
function createSmallOutlineStyles(theme: Theme): IStyles {
|
|
295
|
+
const commonStyles = createThemedStyles(theme);
|
|
296
|
+
return StyleSheet.create({
|
|
297
|
+
button: {
|
|
298
|
+
padding: Spacing.medium,
|
|
299
|
+
alignItems: 'center',
|
|
300
|
+
justifyContent: 'center',
|
|
301
|
+
borderRadius: BorderRadius.extraLarge,
|
|
302
|
+
flexDirection: 'row',
|
|
303
|
+
backgroundColor: 'transparent',
|
|
304
|
+
width: 175,
|
|
305
|
+
borderColor: theme.colors.indigoBlue,
|
|
306
|
+
borderWidth: 1,
|
|
307
|
+
} as ViewStyle,
|
|
308
|
+
label: {
|
|
309
|
+
...commonStyles.normalText,
|
|
310
|
+
color: theme.colors.indigoBlue,
|
|
311
|
+
} as TextStyle,
|
|
312
|
+
icon: {
|
|
313
|
+
width: 22,
|
|
314
|
+
height: 22,
|
|
315
|
+
resizeMode: 'contain',
|
|
316
|
+
tintColor: theme.colors.indigoBlue,
|
|
317
|
+
} as ImageStyle,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {Text, TextProps, StyleSheet, TextStyle} from 'react-native';
|
|
3
|
+
import {useRTL} from '../localization/LocalizationProvider';
|
|
4
|
+
|
|
5
|
+
interface RTLAwareTextProps extends TextProps {
|
|
6
|
+
style?: TextStyle | TextStyle[];
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A Text component that automatically adjusts its layout for RTL languages
|
|
12
|
+
* It flips text alignment and other text-specific properties
|
|
13
|
+
*/
|
|
14
|
+
export const RTLAwareText: React.FC<RTLAwareTextProps> = ({
|
|
15
|
+
style,
|
|
16
|
+
children,
|
|
17
|
+
...props
|
|
18
|
+
}) => {
|
|
19
|
+
const isRTL = useRTL();
|
|
20
|
+
|
|
21
|
+
// Convert style array to a single object
|
|
22
|
+
const flattenedStyle = StyleSheet.flatten(style || {});
|
|
23
|
+
|
|
24
|
+
// Create RTL-aware styles
|
|
25
|
+
const rtlStyle: TextStyle = {};
|
|
26
|
+
|
|
27
|
+
// Handle text alignment
|
|
28
|
+
if (flattenedStyle.textAlign === 'left') {
|
|
29
|
+
rtlStyle.textAlign = isRTL ? 'right' : 'left';
|
|
30
|
+
} else if (flattenedStyle.textAlign === 'right') {
|
|
31
|
+
rtlStyle.textAlign = isRTL ? 'left' : 'right';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Handle writing direction
|
|
35
|
+
rtlStyle.writingDirection = isRTL ? 'rtl' : 'ltr';
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<Text style={[style, rtlStyle]} {...props}>
|
|
39
|
+
{children}
|
|
40
|
+
</Text>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
ViewProps,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
TextStyle,
|
|
7
|
+
ViewStyle,
|
|
8
|
+
FlexStyle,
|
|
9
|
+
TouchableOpacity,
|
|
10
|
+
TouchableOpacityProps,
|
|
11
|
+
} from 'react-native';
|
|
12
|
+
import {useRTL} from '../localization/LocalizationProvider';
|
|
13
|
+
|
|
14
|
+
interface RTLAwareViewProps extends ViewProps {
|
|
15
|
+
style?: ViewStyle | ViewStyle[];
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface RTLAwareTouchableOpacityProps extends TouchableOpacityProps {
|
|
20
|
+
style?: ViewStyle | ViewStyle[];
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A View component that automatically adjusts its layout for RTL languages
|
|
26
|
+
* It flips certain style properties like flexDirection, textAlign, etc.
|
|
27
|
+
*/
|
|
28
|
+
export const RTLAwareView: React.FC<RTLAwareViewProps> = ({
|
|
29
|
+
style,
|
|
30
|
+
children,
|
|
31
|
+
...props
|
|
32
|
+
}) => {
|
|
33
|
+
const isRTL = useRTL();
|
|
34
|
+
|
|
35
|
+
// Convert style array to a single object
|
|
36
|
+
const flattenedStyle = StyleSheet.flatten(style || {});
|
|
37
|
+
|
|
38
|
+
// Create RTL-aware styles
|
|
39
|
+
const rtlStyle: ViewStyle = {};
|
|
40
|
+
|
|
41
|
+
// Handle flexDirection
|
|
42
|
+
if (flattenedStyle.flexDirection === 'row') {
|
|
43
|
+
rtlStyle.flexDirection = isRTL ? 'row-reverse' : 'row';
|
|
44
|
+
} else if (flattenedStyle.flexDirection === 'row-reverse') {
|
|
45
|
+
rtlStyle.flexDirection = isRTL ? 'row' : 'row-reverse';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Handle text alignment
|
|
49
|
+
if ((flattenedStyle as TextStyle).textAlign === 'left') {
|
|
50
|
+
(rtlStyle as TextStyle).textAlign = isRTL ? 'right' : 'left';
|
|
51
|
+
} else if ((flattenedStyle as TextStyle).textAlign === 'right') {
|
|
52
|
+
(rtlStyle as TextStyle).textAlign = isRTL ? 'left' : 'right';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Handle padding and margin
|
|
56
|
+
if (flattenedStyle.paddingStart !== undefined) {
|
|
57
|
+
rtlStyle.paddingLeft = isRTL ? undefined : flattenedStyle.paddingStart;
|
|
58
|
+
rtlStyle.paddingRight = isRTL ? flattenedStyle.paddingStart : undefined;
|
|
59
|
+
rtlStyle.paddingStart = undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (flattenedStyle.paddingEnd !== undefined) {
|
|
63
|
+
rtlStyle.paddingRight = isRTL ? undefined : flattenedStyle.paddingEnd;
|
|
64
|
+
rtlStyle.paddingLeft = isRTL ? flattenedStyle.paddingEnd : undefined;
|
|
65
|
+
rtlStyle.paddingEnd = undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (flattenedStyle.marginStart !== undefined) {
|
|
69
|
+
rtlStyle.marginLeft = isRTL ? undefined : flattenedStyle.marginStart;
|
|
70
|
+
rtlStyle.marginRight = isRTL ? flattenedStyle.marginStart : undefined;
|
|
71
|
+
rtlStyle.marginStart = undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (flattenedStyle.marginEnd !== undefined) {
|
|
75
|
+
rtlStyle.marginRight = isRTL ? undefined : flattenedStyle.marginEnd;
|
|
76
|
+
rtlStyle.marginLeft = isRTL ? flattenedStyle.marginEnd : undefined;
|
|
77
|
+
rtlStyle.marginEnd = undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<View style={[style, rtlStyle]} {...props}>
|
|
82
|
+
{children}
|
|
83
|
+
</View>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const RTLAwareTouchableOpacity: React.FC<
|
|
88
|
+
RTLAwareTouchableOpacityProps
|
|
89
|
+
> = ({style, children, ...props}) => {
|
|
90
|
+
const isRTL = useRTL();
|
|
91
|
+
|
|
92
|
+
// Convert style array to a single object
|
|
93
|
+
const flattenedStyle = StyleSheet.flatten(style || {});
|
|
94
|
+
|
|
95
|
+
// Create RTL-aware styles
|
|
96
|
+
const rtlStyle: ViewStyle = {};
|
|
97
|
+
|
|
98
|
+
// Handle flexDirection
|
|
99
|
+
if (flattenedStyle.flexDirection === 'row') {
|
|
100
|
+
rtlStyle.flexDirection = isRTL ? 'row-reverse' : 'row';
|
|
101
|
+
} else if (flattenedStyle.flexDirection === 'row-reverse') {
|
|
102
|
+
rtlStyle.flexDirection = isRTL ? 'row' : 'row-reverse';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Handle text alignment
|
|
106
|
+
if ((flattenedStyle as TextStyle).textAlign === 'left') {
|
|
107
|
+
(rtlStyle as TextStyle).textAlign = isRTL ? 'right' : 'left';
|
|
108
|
+
} else if ((flattenedStyle as TextStyle).textAlign === 'right') {
|
|
109
|
+
(rtlStyle as TextStyle).textAlign = isRTL ? 'left' : 'right';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Handle padding and margin
|
|
113
|
+
if (flattenedStyle.paddingStart !== undefined) {
|
|
114
|
+
rtlStyle.paddingLeft = isRTL ? undefined : flattenedStyle.paddingStart;
|
|
115
|
+
rtlStyle.paddingRight = isRTL ? flattenedStyle.paddingStart : undefined;
|
|
116
|
+
rtlStyle.paddingStart = undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (flattenedStyle.paddingEnd !== undefined) {
|
|
120
|
+
rtlStyle.paddingRight = isRTL ? undefined : flattenedStyle.paddingEnd;
|
|
121
|
+
rtlStyle.paddingLeft = isRTL ? flattenedStyle.paddingEnd : undefined;
|
|
122
|
+
rtlStyle.paddingEnd = undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (flattenedStyle.marginStart !== undefined) {
|
|
126
|
+
rtlStyle.marginLeft = isRTL ? undefined : flattenedStyle.marginStart;
|
|
127
|
+
rtlStyle.marginRight = isRTL ? flattenedStyle.marginStart : undefined;
|
|
128
|
+
rtlStyle.marginStart = undefined;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (flattenedStyle.marginEnd !== undefined) {
|
|
132
|
+
rtlStyle.marginRight = isRTL ? undefined : flattenedStyle.marginEnd;
|
|
133
|
+
rtlStyle.marginLeft = isRTL ? flattenedStyle.marginEnd : undefined;
|
|
134
|
+
rtlStyle.marginEnd = undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<TouchableOpacity style={[style, rtlStyle]} {...props}>
|
|
139
|
+
{children}
|
|
140
|
+
</TouchableOpacity>
|
|
141
|
+
);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* A Text component that automatically adjusts its layout for RTL languages
|
|
146
|
+
*/
|
|
147
|
+
export const rtlStyles = (isRTL: boolean) => ({
|
|
148
|
+
// Text alignment
|
|
149
|
+
textLeft: {
|
|
150
|
+
textAlign: isRTL ? 'right' : 'left',
|
|
151
|
+
} as TextStyle,
|
|
152
|
+
textRight: {
|
|
153
|
+
textAlign: isRTL ? 'left' : 'right',
|
|
154
|
+
} as TextStyle,
|
|
155
|
+
|
|
156
|
+
// Flex direction
|
|
157
|
+
row: {
|
|
158
|
+
flexDirection: isRTL ? 'row-reverse' : 'row',
|
|
159
|
+
} as FlexStyle,
|
|
160
|
+
rowReverse: {
|
|
161
|
+
flexDirection: isRTL ? 'row' : 'row-reverse',
|
|
162
|
+
} as FlexStyle,
|
|
163
|
+
|
|
164
|
+
// Alignment
|
|
165
|
+
alignStart: {
|
|
166
|
+
alignItems: isRTL ? 'flex-end' : 'flex-start',
|
|
167
|
+
} as FlexStyle,
|
|
168
|
+
alignEnd: {
|
|
169
|
+
alignItems: isRTL ? 'flex-start' : 'flex-end',
|
|
170
|
+
} as FlexStyle,
|
|
171
|
+
|
|
172
|
+
// Justify content
|
|
173
|
+
justifyStart: {
|
|
174
|
+
justifyContent: isRTL ? 'flex-end' : 'flex-start',
|
|
175
|
+
} as FlexStyle,
|
|
176
|
+
justifyEnd: {
|
|
177
|
+
justifyContent: isRTL ? 'flex-start' : 'flex-end',
|
|
178
|
+
} as FlexStyle,
|
|
179
|
+
});
|
|
@@ -4,7 +4,6 @@ import {RadioIcon} from './RadioIcon';
|
|
|
4
4
|
import {TouchablePlatform} from './TouchablePlatform';
|
|
5
5
|
import {CommonSizes} from '../../core/theme/commonSizes';
|
|
6
6
|
import {CommonStyles} from '../../core/theme/commonStyles';
|
|
7
|
-
import {Colors} from '../../core/theme/colors';
|
|
8
7
|
|
|
9
8
|
interface IIconComponentProps {
|
|
10
9
|
isSelected: boolean;
|
|
@@ -31,7 +30,7 @@ export const RadioButton: FC<IProps> = memo(
|
|
|
31
30
|
return (
|
|
32
31
|
<TouchablePlatform
|
|
33
32
|
style={styles.container}
|
|
34
|
-
|
|
33
|
+
onPressIn={onButtonPress}
|
|
35
34
|
disabled={disabled}>
|
|
36
35
|
{IconComponent && (
|
|
37
36
|
<IconComponent disabled={disabled} isSelected={isSelected} />
|
|
@@ -61,6 +60,5 @@ const styles = StyleSheet.create({
|
|
|
61
60
|
} as TextStyle,
|
|
62
61
|
labelDisabled: {
|
|
63
62
|
...commonLabel,
|
|
64
|
-
color: Colors.gray,
|
|
65
63
|
} as TextStyle,
|
|
66
64
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, {FC, memo, useMemo} from 'react';
|
|
2
2
|
import {StyleSheet, View, ViewStyle} from 'react-native';
|
|
3
|
-
import {
|
|
3
|
+
import {NewColors} from '../../core/theme/colors';
|
|
4
4
|
|
|
5
5
|
interface IProps {
|
|
6
6
|
isSelected: boolean;
|
|
@@ -30,7 +30,6 @@ const commonOuterCircle: ViewStyle = {
|
|
|
30
30
|
borderWidth: 2,
|
|
31
31
|
justifyContent: 'center',
|
|
32
32
|
alignItems: 'center',
|
|
33
|
-
backgroundColor: Colors.transparent,
|
|
34
33
|
};
|
|
35
34
|
|
|
36
35
|
const commonInnerCircle: ViewStyle = {
|