@momo-kits/foundation 0.150.2-phuc.13 → 0.150.2-scaleSize.35
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/Application/BottomSheet.tsx +39 -114
- package/Application/BottomTab/Badge.tsx +15 -2
- package/Application/BottomTab/BottomTabBar.tsx +1 -1
- package/Application/BottomTab/CustomBottomTabItem.tsx +5 -3
- package/Application/BottomTab/TabBarIcon.tsx +8 -6
- package/Application/BottomTab/index.tsx +82 -87
- package/Application/Components/BackgroundImageView.tsx +1 -1
- package/Application/Components/HeaderAnimated.tsx +12 -11
- package/Application/Components/HeaderBackground.tsx +1 -1
- package/Application/Components/HeaderExtendHeader.tsx +31 -26
- package/Application/Components/HeaderLeft.tsx +2 -2
- package/Application/Components/HeaderRight.tsx +24 -20
- package/Application/Components/HeaderTitle.tsx +19 -7
- package/Application/Components/NavigationButton.tsx +12 -11
- package/Application/Components/SearchHeader.tsx +20 -3
- package/Application/ModalScreen.tsx +14 -1
- package/Application/NavigationContainer.tsx +13 -7
- package/Application/StackScreen.tsx +100 -155
- package/Application/WidgetContainer.tsx +1 -1
- package/Application/index.ts +12 -31
- package/Application/types.ts +66 -18
- package/Application/utils.tsx +41 -17
- package/Assets/language.json +6 -2
- package/Assets/lottie_circle_loader.json +1 -0
- package/Badge/Badge.tsx +14 -11
- package/Badge/BadgeRibbon.tsx +1 -1
- package/Button/index.tsx +47 -32
- package/CheckBox/index.tsx +23 -19
- package/CheckBox/styles.ts +1 -0
- package/Context/index.ts +23 -0
- package/Divider/DashDivider.tsx +10 -9
- package/Divider/index.tsx +7 -7
- package/FoundationList/index.tsx +7 -4
- package/Icon/index.tsx +9 -9
- package/IconButton/index.tsx +12 -10
- package/Image/index.tsx +9 -2
- package/Input/Input.tsx +3 -5
- package/Input/InputDropDown.tsx +31 -23
- package/Input/InputMoney.tsx +3 -5
- package/Input/InputOTP.tsx +7 -7
- package/Input/InputPhoneNumber.tsx +271 -0
- package/Input/InputSearch.tsx +3 -5
- package/Input/InputTextArea.tsx +2 -1
- package/Input/TextTyping.tsx +8 -2
- package/Input/common.tsx +31 -24
- package/Input/index.tsx +21 -1
- package/Input/styles.ts +17 -12
- package/Input/utils.ts +42 -1
- package/Layout/Card.tsx +4 -3
- package/Layout/FloatingButton.tsx +1 -1
- package/Layout/GridSystem.tsx +15 -14
- package/Layout/Item.tsx +1 -1
- package/Layout/Screen.tsx +8 -5
- package/Layout/Section.tsx +1 -1
- package/Layout/TrackingScope.tsx +3 -3
- package/Loader/DotLoader.tsx +7 -7
- package/Loader/ProgressBar.tsx +10 -9
- package/Loader/Spinner.tsx +7 -7
- package/Pagination/Dot.tsx +10 -7
- package/Pagination/PaginationDot.tsx +8 -8
- package/Pagination/PaginationScroll.tsx +12 -10
- package/Popup/PopupNotify.tsx +2 -2
- package/Popup/PopupPromotion.tsx +1 -1
- package/Radio/index.tsx +18 -18
- package/Skeleton/index.tsx +1 -1
- package/Switch/index.tsx +17 -12
- package/Text/index.tsx +4 -4
- package/Text/styles.ts +37 -36
- package/Text/types.ts +1 -0
- package/Text/utils.ts +33 -4
- package/Title/index.tsx +48 -29
- package/index.ts +1 -0
- package/package.json +35 -34
- package/Application/Components/index.ts +0 -7
|
@@ -1,28 +1,17 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
useCallback,
|
|
3
|
-
useContext,
|
|
4
|
-
useEffect,
|
|
5
|
-
useMemo,
|
|
6
|
-
useRef,
|
|
7
|
-
useState,
|
|
8
|
-
} from 'react';
|
|
1
|
+
import React, { useCallback, useContext, useEffect, useRef } from 'react';
|
|
9
2
|
import {
|
|
10
3
|
Dimensions,
|
|
11
|
-
Keyboard,
|
|
12
4
|
KeyboardAvoidingView,
|
|
13
|
-
KeyboardEventName,
|
|
14
|
-
LayoutAnimation,
|
|
15
5
|
Modal,
|
|
16
6
|
PanResponder,
|
|
17
7
|
Platform,
|
|
18
8
|
Pressable,
|
|
19
|
-
ScrollView,
|
|
20
9
|
StyleSheet,
|
|
21
10
|
TouchableOpacity,
|
|
22
11
|
View,
|
|
23
12
|
} from 'react-native';
|
|
24
13
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
25
|
-
import { ApplicationContext } from '
|
|
14
|
+
import { ApplicationContext } from '../Context';
|
|
26
15
|
import { BottomSheetParams } from './types';
|
|
27
16
|
import { Colors, Radius, Spacing, Styles } from '../Consts';
|
|
28
17
|
import { Text } from '../Text';
|
|
@@ -31,12 +20,12 @@ import { useHeaderHeight } from '@react-navigation/elements';
|
|
|
31
20
|
import Animated, {
|
|
32
21
|
Easing,
|
|
33
22
|
Extrapolate,
|
|
34
|
-
useSharedValue,
|
|
35
|
-
useAnimatedStyle,
|
|
36
|
-
withTiming,
|
|
37
|
-
withSpring,
|
|
38
23
|
interpolate,
|
|
39
24
|
runOnJS,
|
|
25
|
+
useAnimatedStyle,
|
|
26
|
+
useSharedValue,
|
|
27
|
+
withSpring,
|
|
28
|
+
withTiming,
|
|
40
29
|
} from 'react-native-reanimated';
|
|
41
30
|
import layoutStyles from '../Layout/styles';
|
|
42
31
|
|
|
@@ -46,8 +35,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
46
35
|
const action = useRef<undefined | string>(undefined);
|
|
47
36
|
const insets = useSafeAreaInsets();
|
|
48
37
|
const heightHeader = useHeaderHeight();
|
|
49
|
-
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
50
|
-
const [contentHeight, setContentHeight] = useState(0);
|
|
51
38
|
const keyboardOffset = heightHeader - Math.min(insets.bottom, 21);
|
|
52
39
|
|
|
53
40
|
const {
|
|
@@ -59,10 +46,10 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
59
46
|
draggable = true,
|
|
60
47
|
useBottomInset = true,
|
|
61
48
|
useKeyboardAvoidingView = true,
|
|
62
|
-
useScrollOverflow = false,
|
|
63
49
|
keyboardVerticalOffset,
|
|
64
50
|
useDivider = true,
|
|
65
51
|
footerComponent,
|
|
52
|
+
leftOptions,
|
|
66
53
|
}: BottomSheetParams = props.route.params;
|
|
67
54
|
|
|
68
55
|
const translateY = useSharedValue(heightDevice);
|
|
@@ -116,73 +103,14 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
116
103
|
).current;
|
|
117
104
|
|
|
118
105
|
let Container: any = View;
|
|
119
|
-
let Content: any = View;
|
|
120
106
|
if (useNativeModal) {
|
|
121
107
|
Container = Modal;
|
|
122
108
|
}
|
|
123
|
-
if (useScrollOverflow) {
|
|
124
|
-
Content = ScrollView;
|
|
125
|
-
}
|
|
126
109
|
let backgroundColor = theme.colors.background.default;
|
|
127
110
|
if (surface) {
|
|
128
111
|
backgroundColor = theme.colors.background.surface;
|
|
129
112
|
}
|
|
130
113
|
|
|
131
|
-
const headerHeight = 90;
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* If the content height exceeds the device height,
|
|
135
|
-
* adjust bottomInset based on keyboard behavior so the BottomSheet content stays fixed
|
|
136
|
-
* whether the keyboard is open or closed.
|
|
137
|
-
*/
|
|
138
|
-
|
|
139
|
-
let bottomInset: number;
|
|
140
|
-
if (keyboardHeight > 0) {
|
|
141
|
-
bottomInset =
|
|
142
|
-
Platform.select({
|
|
143
|
-
ios: 0,
|
|
144
|
-
android: 21,
|
|
145
|
-
}) ?? 0;
|
|
146
|
-
} else {
|
|
147
|
-
bottomInset =
|
|
148
|
-
Platform.select({
|
|
149
|
-
ios: Math.min(insets.bottom, 21),
|
|
150
|
-
android: -21,
|
|
151
|
-
}) ?? 0;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const maxContentSize =
|
|
155
|
-
heightDevice - headerHeight - keyboardHeight - bottomInset;
|
|
156
|
-
|
|
157
|
-
useEffect(() => {
|
|
158
|
-
let showEvent: KeyboardEventName;
|
|
159
|
-
let hideEvent: KeyboardEventName;
|
|
160
|
-
|
|
161
|
-
if (Platform.OS === 'ios') {
|
|
162
|
-
showEvent = 'keyboardWillShow';
|
|
163
|
-
hideEvent = 'keyboardWillHide';
|
|
164
|
-
} else {
|
|
165
|
-
showEvent = 'keyboardDidShow';
|
|
166
|
-
hideEvent = 'keyboardDidHide';
|
|
167
|
-
}
|
|
168
|
-
const onKeyboardShow = (e: any) => {
|
|
169
|
-
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
|
170
|
-
setKeyboardHeight(e.endCoordinates.height);
|
|
171
|
-
};
|
|
172
|
-
const onKeyboardHide = () => {
|
|
173
|
-
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
|
174
|
-
setKeyboardHeight(0);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
const showSub = Keyboard.addListener(showEvent, onKeyboardShow);
|
|
178
|
-
const hideSub = Keyboard.addListener(hideEvent, onKeyboardHide);
|
|
179
|
-
|
|
180
|
-
return () => {
|
|
181
|
-
showSub.remove();
|
|
182
|
-
hideSub.remove();
|
|
183
|
-
};
|
|
184
|
-
}, []);
|
|
185
|
-
|
|
186
114
|
/**
|
|
187
115
|
* emit dismiss event
|
|
188
116
|
*/
|
|
@@ -194,17 +122,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
194
122
|
};
|
|
195
123
|
}, [heightDevice, openAnimation, props.route.params, translateY]);
|
|
196
124
|
|
|
197
|
-
/**
|
|
198
|
-
* handle content bottom sheet change
|
|
199
|
-
* @param width
|
|
200
|
-
* @param height
|
|
201
|
-
*/
|
|
202
|
-
const handleContentSizeChange = (width: number, height: number) => {
|
|
203
|
-
if (contentHeight !== height) {
|
|
204
|
-
setContentHeight(height);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
125
|
/**
|
|
209
126
|
* handler dismiss
|
|
210
127
|
*/
|
|
@@ -214,8 +131,8 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
214
131
|
return;
|
|
215
132
|
}
|
|
216
133
|
closeAnimation(() => {
|
|
134
|
+
navigator?.pop();
|
|
217
135
|
runOnJS(() => {
|
|
218
|
-
navigator?.pop();
|
|
219
136
|
callback?.();
|
|
220
137
|
})();
|
|
221
138
|
});
|
|
@@ -238,14 +155,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
238
155
|
*/
|
|
239
156
|
const renderHeader = useCallback(() => {
|
|
240
157
|
return (
|
|
241
|
-
<View
|
|
242
|
-
style={{
|
|
243
|
-
backgroundColor,
|
|
244
|
-
borderTopLeftRadius: Radius.M,
|
|
245
|
-
borderTopRightRadius: Radius.M,
|
|
246
|
-
}}
|
|
247
|
-
{...panResponder.panHandlers}
|
|
248
|
-
>
|
|
158
|
+
<View {...panResponder.panHandlers}>
|
|
249
159
|
<View style={{ height: 16 }}>
|
|
250
160
|
<View style={styles.indicator} />
|
|
251
161
|
</View>
|
|
@@ -258,11 +168,22 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
258
168
|
},
|
|
259
169
|
]}
|
|
260
170
|
>
|
|
171
|
+
{leftOptions?.onPressIconLeft ? (
|
|
172
|
+
<TouchableOpacity
|
|
173
|
+
style={styles.iconButton}
|
|
174
|
+
onPress={() => {
|
|
175
|
+
onDismiss(true, leftOptions.onPressIconLeft);
|
|
176
|
+
}}
|
|
177
|
+
>
|
|
178
|
+
<Icon source={leftOptions.iconLeft ?? 'ic_back'} />
|
|
179
|
+
</TouchableOpacity>
|
|
180
|
+
) : null}
|
|
181
|
+
|
|
261
182
|
{options.header ? (
|
|
262
183
|
<View style={Styles.flex}>{options.header}</View>
|
|
263
184
|
) : (
|
|
264
185
|
<>
|
|
265
|
-
<View style={styles.iconButton} />
|
|
186
|
+
{!leftOptions ? <View style={styles.iconButton} /> : null}
|
|
266
187
|
<Text
|
|
267
188
|
style={[Styles.flex, { textAlign: 'center' }]}
|
|
268
189
|
numberOfLines={1}
|
|
@@ -285,8 +206,8 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
285
206
|
</View>
|
|
286
207
|
);
|
|
287
208
|
}, [
|
|
288
|
-
backgroundColor,
|
|
289
209
|
onDismiss,
|
|
210
|
+
leftOptions,
|
|
290
211
|
options.header,
|
|
291
212
|
options.title,
|
|
292
213
|
panResponder.panHandlers,
|
|
@@ -297,7 +218,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
297
218
|
const animatedStyle = useAnimatedStyle(() => {
|
|
298
219
|
return {
|
|
299
220
|
transform: [{ translateY: translateY.value }],
|
|
300
|
-
maxHeight: maxContentSize,
|
|
301
221
|
};
|
|
302
222
|
});
|
|
303
223
|
|
|
@@ -320,6 +240,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
320
240
|
onDismiss();
|
|
321
241
|
}}
|
|
322
242
|
style={StyleSheet.absoluteFillObject}
|
|
243
|
+
isModalKit={true}
|
|
323
244
|
>
|
|
324
245
|
<KeyboardAvoidingView
|
|
325
246
|
behavior={Platform.select({
|
|
@@ -341,19 +262,23 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
341
262
|
<Animated.View style={[styles.overlay, animatedOverlayStyle]} />
|
|
342
263
|
</Pressable>
|
|
343
264
|
|
|
344
|
-
<Animated.View
|
|
265
|
+
<Animated.View
|
|
266
|
+
style={[
|
|
267
|
+
animatedStyle,
|
|
268
|
+
{
|
|
269
|
+
backgroundColor,
|
|
270
|
+
borderTopLeftRadius: Radius.M,
|
|
271
|
+
borderTopRightRadius: Radius.M,
|
|
272
|
+
overflow: 'hidden',
|
|
273
|
+
},
|
|
274
|
+
]}
|
|
275
|
+
>
|
|
345
276
|
{renderHeader()}
|
|
346
|
-
<
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
<Screen
|
|
352
|
-
{...props}
|
|
353
|
-
{...props.route.params}
|
|
354
|
-
onRequestClose={onRequestClose}
|
|
355
|
-
/>
|
|
356
|
-
</Content>
|
|
277
|
+
<Screen
|
|
278
|
+
{...props}
|
|
279
|
+
{...props.route.params}
|
|
280
|
+
onRequestClose={onRequestClose}
|
|
281
|
+
/>
|
|
357
282
|
{footerComponent && (
|
|
358
283
|
<View
|
|
359
284
|
style={[
|
|
@@ -77,6 +77,18 @@ export function Badge({
|
|
|
77
77
|
const borderRadius = size / 2;
|
|
78
78
|
const fontSize = Math.floor((size * 3) / 4);
|
|
79
79
|
|
|
80
|
+
const isNumber = () => {
|
|
81
|
+
const numberRegex = /^\d+$/;
|
|
82
|
+
return numberRegex.test(String(children));
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const formatTitle = () => {
|
|
86
|
+
if (isNumber() && Number(children) > 99) {
|
|
87
|
+
return '99+';
|
|
88
|
+
}
|
|
89
|
+
return children;
|
|
90
|
+
};
|
|
91
|
+
|
|
80
92
|
return (
|
|
81
93
|
<Animated.Text
|
|
82
94
|
numberOfLines={1}
|
|
@@ -103,8 +115,9 @@ export function Badge({
|
|
|
103
115
|
styles.container,
|
|
104
116
|
restStyle,
|
|
105
117
|
]}
|
|
106
|
-
{...rest}
|
|
107
|
-
|
|
118
|
+
{...rest}
|
|
119
|
+
>
|
|
120
|
+
{formatTitle()}
|
|
108
121
|
</Animated.Text>
|
|
109
122
|
);
|
|
110
123
|
}
|
|
@@ -14,8 +14,8 @@ import { Colors, Radius, Styles } from '../../Consts';
|
|
|
14
14
|
import { Icon } from '../../Icon';
|
|
15
15
|
import { Text } from '../../Text';
|
|
16
16
|
import { FloatingButtonProps } from '../types';
|
|
17
|
-
import { ApplicationContext } from '../index';
|
|
18
17
|
import CustomBottomTabItem from './CustomBottomTabItem';
|
|
18
|
+
import { ApplicationContext } from '../../Context';
|
|
19
19
|
|
|
20
20
|
type Props = BottomTabBarProps & {
|
|
21
21
|
activeTintColor?: string;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { TouchableOpacity, StyleSheet, Platform } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
BottomTabBarButtonProps,
|
|
5
|
+
BottomTabNavigationOptions,
|
|
6
|
+
} from '@react-navigation/bottom-tabs';
|
|
7
|
+
import { Route } from '@react-navigation/native';
|
|
3
8
|
import { TabBarIcon } from './TabBarIcon';
|
|
4
9
|
import { Text } from '../../Text';
|
|
5
10
|
|
|
6
|
-
import { Route } from '@react-navigation/native';
|
|
7
|
-
import { BottomTabBarButtonProps, BottomTabNavigationOptions } from '@react-navigation/bottom-tabs';
|
|
8
|
-
|
|
9
11
|
type LabelType = NonNullable<BottomTabNavigationOptions['tabBarLabel']>;
|
|
10
12
|
|
|
11
13
|
interface CustomBottomTabItemProps {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {Route} from '@react-navigation/native';
|
|
1
|
+
import type { Route } from '@react-navigation/native';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import {
|
|
4
4
|
type StyleProp,
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
type ViewStyle,
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
|
|
11
|
-
import {Badge} from './Badge';
|
|
12
|
-
import {Colors} from '../../Consts';
|
|
11
|
+
import { Badge } from './Badge';
|
|
12
|
+
import { Colors } from '../../Consts';
|
|
13
13
|
|
|
14
14
|
type Props = {
|
|
15
15
|
route: Route<string>;
|
|
@@ -60,14 +60,15 @@ export function TabBarIcon({
|
|
|
60
60
|
// Workaround for react-native >= 0.54 layout bug
|
|
61
61
|
minWidth: iconSize,
|
|
62
62
|
},
|
|
63
|
-
]}
|
|
63
|
+
]}
|
|
64
|
+
>
|
|
64
65
|
{renderIcon({
|
|
65
66
|
focused: true,
|
|
66
67
|
size: iconSize,
|
|
67
68
|
color: activeTintColor ?? Colors.black_20,
|
|
68
69
|
})}
|
|
69
70
|
</View>
|
|
70
|
-
<View style={[styles.icon, {opacity: inactiveOpacity}]}>
|
|
71
|
+
<View style={[styles.icon, { opacity: inactiveOpacity }]}>
|
|
71
72
|
{renderIcon({
|
|
72
73
|
focused: false,
|
|
73
74
|
size: iconSize,
|
|
@@ -78,7 +79,8 @@ export function TabBarIcon({
|
|
|
78
79
|
visible={badge != null}
|
|
79
80
|
size={badge === '' ? 12 : iconSize * 0.75}
|
|
80
81
|
allowFontScaling={allowFontScaling}
|
|
81
|
-
style={[styles.badge, badgeStyle]}
|
|
82
|
+
style={[styles.badge, badgeStyle]}
|
|
83
|
+
>
|
|
82
84
|
{badge}
|
|
83
85
|
</Badge>
|
|
84
86
|
</View>
|
|
@@ -5,13 +5,7 @@ import {
|
|
|
5
5
|
useFocusEffect,
|
|
6
6
|
} from '@react-navigation/native';
|
|
7
7
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
8
|
-
import React, {
|
|
9
|
-
useCallback,
|
|
10
|
-
useContext,
|
|
11
|
-
useEffect,
|
|
12
|
-
useLayoutEffect,
|
|
13
|
-
useRef,
|
|
14
|
-
} from 'react';
|
|
8
|
+
import React, { useContext, useEffect, useLayoutEffect, useRef } from 'react';
|
|
15
9
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
16
10
|
import {
|
|
17
11
|
Animated,
|
|
@@ -24,11 +18,11 @@ import {
|
|
|
24
18
|
import { Colors } from '../../Consts';
|
|
25
19
|
import { Icon } from '../../Icon';
|
|
26
20
|
import { exportFontFamily, Text } from '../../Text';
|
|
27
|
-
import { ApplicationContext, MiniAppContext } from '../index';
|
|
28
21
|
import StackScreen from '../StackScreen';
|
|
29
22
|
import { BottomTabProps } from '../types';
|
|
30
|
-
import { getOptions, getStackOptions } from '../utils';
|
|
23
|
+
import { getOptions, getStackOptions, useAppState } from '../utils';
|
|
31
24
|
import BottomTabBar from './BottomTabBar';
|
|
25
|
+
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
32
26
|
|
|
33
27
|
const Tab = createBottomTabNavigator();
|
|
34
28
|
const Stack = createStackNavigator();
|
|
@@ -37,7 +31,6 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
37
31
|
const { navigator } = useContext(ApplicationContext);
|
|
38
32
|
const context = useContext<any>(MiniAppContext);
|
|
39
33
|
const { nested, options, screen, initialParams } = route?.params;
|
|
40
|
-
const useAnimation = route?.params?.useAnimation ?? true;
|
|
41
34
|
const insets = useSafeAreaInsets();
|
|
42
35
|
|
|
43
36
|
const opacityValue = 0.3;
|
|
@@ -45,12 +38,13 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
45
38
|
const opacity = useRef(new Animated.Value(opacityValue)).current;
|
|
46
39
|
const scale = useRef(new Animated.Value(scaleValue)).current;
|
|
47
40
|
const screenName = screen?.name || screen?.type?.name || 'Invalid';
|
|
41
|
+
const { isBackgroundToForeground } = useAppState();
|
|
48
42
|
|
|
49
|
-
const onScreenNavigated =
|
|
50
|
-
(
|
|
43
|
+
const onScreenNavigated = (pre: string, current: string) => {
|
|
44
|
+
if (!isBackgroundToForeground) {
|
|
51
45
|
const data: any = {
|
|
52
|
-
preScreenName,
|
|
53
|
-
screenName,
|
|
46
|
+
preScreenName: pre,
|
|
47
|
+
screenName: current,
|
|
54
48
|
componentName: 'Screen',
|
|
55
49
|
state: 'navigated',
|
|
56
50
|
action: 'push',
|
|
@@ -69,80 +63,82 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
69
63
|
message: `${screenName} screen_navigated`,
|
|
70
64
|
type: 'ERROR',
|
|
71
65
|
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
75
68
|
|
|
76
69
|
useFocusEffect(
|
|
77
|
-
React.useCallback(
|
|
78
|
-
|
|
79
|
-
Animated.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
70
|
+
React.useCallback(
|
|
71
|
+
() => {
|
|
72
|
+
Animated.parallel([
|
|
73
|
+
Animated.timing(opacity, {
|
|
74
|
+
toValue: 1,
|
|
75
|
+
duration: 200,
|
|
76
|
+
useNativeDriver: true,
|
|
77
|
+
}),
|
|
78
|
+
Animated.timing(scale, {
|
|
79
|
+
toValue: 1,
|
|
80
|
+
duration: 200,
|
|
81
|
+
useNativeDriver: true,
|
|
82
|
+
}),
|
|
83
|
+
]).start();
|
|
90
84
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
navigator?.maxApi?.getDataObserver?.(
|
|
87
|
+
'current_screen',
|
|
88
|
+
(data: any) => {
|
|
89
|
+
onScreenNavigated(data?.screenName, screenName);
|
|
90
|
+
navigator?.maxApi?.setObserver?.('current_screen', {
|
|
91
|
+
screenName,
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
}, 100);
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
opacity,
|
|
119
|
-
route?.params.index,
|
|
120
|
-
scale,
|
|
121
|
-
screenName,
|
|
122
|
-
]),
|
|
97
|
+
return () => {
|
|
98
|
+
if (navigation.getState().index !== route?.params.index) {
|
|
99
|
+
Animated.parallel([
|
|
100
|
+
Animated.timing(opacity, {
|
|
101
|
+
toValue: opacityValue,
|
|
102
|
+
duration: 200,
|
|
103
|
+
useNativeDriver: true,
|
|
104
|
+
}),
|
|
105
|
+
Animated.timing(scale, {
|
|
106
|
+
toValue: scaleValue,
|
|
107
|
+
duration: 200,
|
|
108
|
+
useNativeDriver: true,
|
|
109
|
+
}),
|
|
110
|
+
]).start();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
115
|
+
[],
|
|
116
|
+
),
|
|
123
117
|
);
|
|
124
118
|
|
|
125
|
-
useEffect(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
119
|
+
useEffect(
|
|
120
|
+
() => {
|
|
121
|
+
const onFocusApp = navigator?.maxApi?.listen?.('onFocusApp', () => {
|
|
122
|
+
if (navigation.isFocused()) {
|
|
123
|
+
navigator?.maxApi?.getDataObserver?.(
|
|
124
|
+
'current_screen',
|
|
125
|
+
(data: any) => {
|
|
126
|
+
onScreenNavigated(data?.screenName, screenName);
|
|
127
|
+
navigator?.maxApi?.setObserver?.('current_screen', {
|
|
128
|
+
screenName,
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
139
134
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
135
|
+
return () => {
|
|
136
|
+
onFocusApp?.remove?.();
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
140
|
+
[],
|
|
141
|
+
);
|
|
146
142
|
|
|
147
143
|
let stackOptions = {};
|
|
148
144
|
if (options) {
|
|
@@ -155,8 +151,8 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
155
151
|
style={[
|
|
156
152
|
styles.container,
|
|
157
153
|
{
|
|
158
|
-
opacity
|
|
159
|
-
transform: [{ scale
|
|
154
|
+
opacity,
|
|
155
|
+
transform: [{ scale }],
|
|
160
156
|
},
|
|
161
157
|
]}
|
|
162
158
|
>
|
|
@@ -188,8 +184,8 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
188
184
|
style={[
|
|
189
185
|
styles.container,
|
|
190
186
|
{
|
|
191
|
-
opacity
|
|
192
|
-
transform: [{ scale
|
|
187
|
+
opacity,
|
|
188
|
+
transform: [{ scale }],
|
|
193
189
|
},
|
|
194
190
|
]}
|
|
195
191
|
>
|
|
@@ -227,7 +223,6 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
227
223
|
navigation,
|
|
228
224
|
initialRouteName,
|
|
229
225
|
floatingButton,
|
|
230
|
-
useAnimation = true,
|
|
231
226
|
}) => {
|
|
232
227
|
const { theme, navigator } = useContext(ApplicationContext);
|
|
233
228
|
const dimensions = useWindowDimensions();
|
|
@@ -340,7 +335,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
340
335
|
key={`BottomTab-${item.name}`}
|
|
341
336
|
name={item.name}
|
|
342
337
|
component={TabScreen}
|
|
343
|
-
initialParams={{ ...item, nested, index
|
|
338
|
+
initialParams={{ ...item, nested, index }}
|
|
344
339
|
listeners={handler}
|
|
345
340
|
options={{
|
|
346
341
|
tabBarLabel: ({ focused, color }) => {
|
|
@@ -2,7 +2,7 @@ import React, { FC, useContext } from 'react';
|
|
|
2
2
|
import { Animated, Platform, StyleSheet } from 'react-native';
|
|
3
3
|
import { Image } from '../../Image';
|
|
4
4
|
import { Colors } from '../../Consts';
|
|
5
|
-
import { ApplicationContext } from '
|
|
5
|
+
import { ApplicationContext } from '../../Context';
|
|
6
6
|
|
|
7
7
|
type BackgroundImageViewProps = {
|
|
8
8
|
useShadowHeader: boolean;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {Animated, StyleSheet, View} from 'react-native';
|
|
2
|
-
import {HeaderAnimatedProps} from '../types';
|
|
3
|
-
import React, {useContext} from 'react';
|
|
4
|
-
import {Image} from '../../Image';
|
|
5
|
-
import {MiniAppContext} from '
|
|
6
|
-
import {Colors} from '../../Consts';
|
|
1
|
+
import { Animated, StyleSheet, View } from 'react-native';
|
|
2
|
+
import { type HeaderAnimatedProps } from '../types';
|
|
3
|
+
import React, { useContext } from 'react';
|
|
4
|
+
import { Image } from '../../Image';
|
|
5
|
+
import { MiniAppContext } from '../../Context';
|
|
6
|
+
import { Colors } from '../../Consts';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* default header banner for header animated
|
|
@@ -38,9 +38,10 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
|
38
38
|
styles.container,
|
|
39
39
|
{
|
|
40
40
|
opacity: opacity,
|
|
41
|
-
transform: [{scale}, {translateY}],
|
|
41
|
+
transform: [{ scale }, { translateY }],
|
|
42
42
|
},
|
|
43
|
-
]}
|
|
43
|
+
]}
|
|
44
|
+
>
|
|
44
45
|
{children ?? (
|
|
45
46
|
<Image
|
|
46
47
|
source={{
|
|
@@ -63,7 +64,7 @@ const Verified: React.FC<any> = () => {
|
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
const styles = StyleSheet.create({
|
|
66
|
-
container: {width: '100%', aspectRatio: 16 / 9},
|
|
67
|
+
container: { width: '100%', aspectRatio: 16 / 9 },
|
|
67
68
|
verifiedDot: {
|
|
68
69
|
width: 4,
|
|
69
70
|
height: 4,
|
|
@@ -72,7 +73,7 @@ const styles = StyleSheet.create({
|
|
|
72
73
|
position: 'absolute',
|
|
73
74
|
alignSelf: 'center',
|
|
74
75
|
},
|
|
75
|
-
full: {width: '100%', height: '100%'},
|
|
76
|
+
full: { width: '100%', height: '100%' },
|
|
76
77
|
});
|
|
77
78
|
|
|
78
|
-
export {HeaderAnimated};
|
|
79
|
+
export { HeaderAnimated };
|
|
@@ -2,7 +2,7 @@ import LinearGradient from 'react-native-linear-gradient';
|
|
|
2
2
|
import { Animated, StyleSheet, View } from 'react-native';
|
|
3
3
|
import React, { useContext } from 'react';
|
|
4
4
|
import { HeaderBackgroundProps } from '../types';
|
|
5
|
-
import { ApplicationContext } from '
|
|
5
|
+
import { ApplicationContext } from '../../Context';
|
|
6
6
|
import { Styles } from '../../Consts';
|
|
7
7
|
import { Image } from '../../Image';
|
|
8
8
|
import BackgroundImageView from './BackgroundImageView';
|