@momo-kits/foundation 0.160.1-beta.6 → 0.160.1-beta.7
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 +3 -3
- package/Application/BottomTab/BottomTabBar.tsx +17 -17
- package/Application/BottomTab/CustomBottomTabItem.tsx +1 -1
- package/Application/BottomTab/index.tsx +31 -55
- package/Application/Components/BackgroundImageView.tsx +22 -6
- package/Application/Components/HeaderAnimated.tsx +32 -29
- package/Application/Components/HeaderBackground.tsx +21 -27
- package/Application/Components/HeaderExtendHeader.tsx +114 -94
- package/Application/Components/HeaderTitle.tsx +40 -11
- package/Application/Components/SearchHeader.tsx +17 -22
- package/Application/NavigationContainer.tsx +22 -9
- package/Application/ScaleSizeProvider.tsx +16 -0
- package/Application/WidgetContainer.tsx +6 -1
- package/Application/index.ts +2 -0
- package/Application/types.ts +10 -4
- package/Application/utils.tsx +4 -3
- package/Badge/Badge.tsx +3 -9
- package/Badge/BadgeDot.tsx +1 -1
- package/Badge/BadgeDotAnimation.tsx +53 -71
- package/Badge/BadgeRibbon.tsx +1 -1
- package/Button/index.tsx +3 -6
- package/CheckBox/index.tsx +1 -1
- package/Context/index.ts +4 -0
- package/Icon/index.tsx +1 -1
- package/IconButton/index.tsx +1 -1
- package/Image/index.tsx +1 -1
- package/Input/Input.tsx +1 -1
- package/Input/InputDropDown.tsx +1 -1
- package/Input/InputMoney.tsx +1 -1
- package/Input/InputOTP.tsx +39 -24
- package/Input/InputPhoneNumber.tsx +1 -1
- package/Input/InputSearch.tsx +1 -1
- package/Input/InputTextArea.tsx +1 -1
- package/Layout/FloatingButton.tsx +51 -51
- package/Layout/Item.tsx +1 -1
- package/Layout/Screen.tsx +61 -57
- package/Loader/ProgressBar.tsx +20 -18
- package/Pagination/Dot.tsx +2 -2
- package/Pagination/PaginationDot.tsx +1 -1
- package/Pagination/PaginationNumber.tsx +1 -1
- package/Pagination/PaginationScroll.tsx +32 -28
- package/Pagination/PaginationWhiteDot.tsx +1 -1
- package/Popup/PopupNotify.tsx +1 -1
- package/Popup/PopupPromotion.tsx +1 -1
- package/Radio/index.tsx +1 -1
- package/Skeleton/index.tsx +31 -23
- package/Switch/index.tsx +1 -1
- package/Tag/index.tsx +1 -1
- package/Text/index.tsx +1 -1
- package/Text/utils.ts +41 -18
- package/Title/index.tsx +1 -1
- package/package.json +34 -34
|
@@ -20,7 +20,7 @@ import { Icon } from '../Icon';
|
|
|
20
20
|
import { useHeaderHeight } from '@react-navigation/elements';
|
|
21
21
|
import Animated, {
|
|
22
22
|
Easing,
|
|
23
|
-
|
|
23
|
+
Extrapolation,
|
|
24
24
|
interpolate,
|
|
25
25
|
runOnJS,
|
|
26
26
|
useAnimatedStyle,
|
|
@@ -39,7 +39,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
39
39
|
const heightHeader = useHeaderHeight();
|
|
40
40
|
const keyboardOffset = heightHeader - Math.min(insets.bottom, 21);
|
|
41
41
|
|
|
42
|
-
const showBaseLineDebug = context?.
|
|
42
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
43
43
|
|
|
44
44
|
const {
|
|
45
45
|
screen: Screen,
|
|
@@ -242,7 +242,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
242
242
|
translateY.value,
|
|
243
243
|
[0, heightDevice],
|
|
244
244
|
[1, 0],
|
|
245
|
-
|
|
245
|
+
Extrapolation.CLAMP,
|
|
246
246
|
),
|
|
247
247
|
};
|
|
248
248
|
});
|
|
@@ -2,13 +2,17 @@ import { BottomTabBarProps } from '@react-navigation/bottom-tabs';
|
|
|
2
2
|
import { CommonActions, Route } from '@react-navigation/native';
|
|
3
3
|
import React, { useCallback, useContext } from 'react';
|
|
4
4
|
import {
|
|
5
|
-
Animated,
|
|
6
5
|
Platform,
|
|
7
6
|
StyleSheet,
|
|
8
7
|
TouchableOpacity,
|
|
9
8
|
useWindowDimensions,
|
|
10
9
|
View,
|
|
11
10
|
} from 'react-native';
|
|
11
|
+
import Animated, {
|
|
12
|
+
useAnimatedStyle,
|
|
13
|
+
useSharedValue,
|
|
14
|
+
withTiming,
|
|
15
|
+
} from 'react-native-reanimated';
|
|
12
16
|
import { EdgeInsets, useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
13
17
|
import { Colors, Radius, Styles } from '../../Consts';
|
|
14
18
|
import { Icon } from '../../Icon';
|
|
@@ -57,13 +61,18 @@ export default function BottomTabBar({
|
|
|
57
61
|
const useFloating = floatingButton && state.routes.length % 2 === 0;
|
|
58
62
|
const itemWidth = widthDevice / (state.routes.length + (useFloating ? 1 : 0));
|
|
59
63
|
// const buildLink = useLinkBuilder();
|
|
60
|
-
const indicatorAnimated =
|
|
64
|
+
const indicatorAnimated = useSharedValue(0);
|
|
61
65
|
const insets = useSafeAreaInsets();
|
|
66
|
+
|
|
67
|
+
const indicatorStyle = useAnimatedStyle(() => ({
|
|
68
|
+
width: itemWidth,
|
|
69
|
+
transform: [{ translateX: indicatorAnimated.value }],
|
|
70
|
+
}));
|
|
62
71
|
const paddingBottom = getPaddingBottom(insets);
|
|
63
72
|
const focusedTab = state?.routes[state.index]?.name || routes[0]?.params;
|
|
64
73
|
|
|
65
74
|
const context = useContext<any>(MiniAppContext);
|
|
66
|
-
const showBaseLineDebug = context?.
|
|
75
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
67
76
|
|
|
68
77
|
/**
|
|
69
78
|
* render tab item
|
|
@@ -199,11 +208,7 @@ export default function BottomTabBar({
|
|
|
199
208
|
if (useFloating && index > (state.routes.length - 1) / 2) {
|
|
200
209
|
index += 1;
|
|
201
210
|
}
|
|
202
|
-
|
|
203
|
-
toValue: itemWidth * index,
|
|
204
|
-
useNativeDriver: true,
|
|
205
|
-
duration: 200,
|
|
206
|
-
}).start();
|
|
211
|
+
indicatorAnimated.value = withTiming(itemWidth * index, { duration: 200 });
|
|
207
212
|
}, [
|
|
208
213
|
state.index,
|
|
209
214
|
itemWidth,
|
|
@@ -232,7 +237,7 @@ export default function BottomTabBar({
|
|
|
232
237
|
};
|
|
233
238
|
|
|
234
239
|
return (
|
|
235
|
-
<
|
|
240
|
+
<View
|
|
236
241
|
style={[
|
|
237
242
|
floatingButton ? styles.tabBarFloatingButton : styles.tabBar,
|
|
238
243
|
{
|
|
@@ -250,12 +255,7 @@ export default function BottomTabBar({
|
|
|
250
255
|
<View style={styles.content} accessibilityLabel={'bottom_tab_bar'}>
|
|
251
256
|
{useFloating && floatingButton?.container}
|
|
252
257
|
<Animated.View
|
|
253
|
-
style={{
|
|
254
|
-
width: itemWidth,
|
|
255
|
-
position: 'absolute',
|
|
256
|
-
top: 0,
|
|
257
|
-
transform: [{ translateX: indicatorAnimated }],
|
|
258
|
-
}}
|
|
258
|
+
style={[{ position: 'absolute', top: 0 }, indicatorStyle]}
|
|
259
259
|
>
|
|
260
260
|
<View
|
|
261
261
|
style={[
|
|
@@ -266,7 +266,7 @@ export default function BottomTabBar({
|
|
|
266
266
|
</Animated.View>
|
|
267
267
|
{renderTabBar()}
|
|
268
268
|
</View>
|
|
269
|
-
</
|
|
269
|
+
</View>
|
|
270
270
|
);
|
|
271
271
|
}
|
|
272
272
|
|
|
@@ -299,7 +299,7 @@ const styles = StyleSheet.create({
|
|
|
299
299
|
left: 0,
|
|
300
300
|
right: 0,
|
|
301
301
|
top: -2,
|
|
302
|
-
bottom: Platform.OS === 'ios' ? -6 : 4
|
|
302
|
+
bottom: Platform.OS === 'ios' ? -6 : 4
|
|
303
303
|
},
|
|
304
304
|
floatingContent: {
|
|
305
305
|
alignItems: 'center',
|
|
@@ -61,7 +61,7 @@ const CustomBottomTabItem: React.FC<CustomBottomTabItemProps> = ({
|
|
|
61
61
|
allowFontScaling,
|
|
62
62
|
}) => {
|
|
63
63
|
const context = useContext<any>(MiniAppContext);
|
|
64
|
-
const showBaseLineDebug = context?.
|
|
64
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
65
65
|
|
|
66
66
|
const renderIcon = () => {
|
|
67
67
|
if (icon === undefined) {
|
|
@@ -5,16 +5,20 @@ import {
|
|
|
5
5
|
useFocusEffect,
|
|
6
6
|
} from '@react-navigation/native';
|
|
7
7
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
8
|
-
import React, { useContext, useEffect, useLayoutEffect
|
|
8
|
+
import React, { useContext, useEffect, useLayoutEffect } from 'react';
|
|
9
9
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
10
10
|
import {
|
|
11
|
-
Animated,
|
|
12
11
|
Platform,
|
|
13
12
|
StatusBar,
|
|
14
13
|
StyleSheet,
|
|
15
14
|
useWindowDimensions,
|
|
16
15
|
View,
|
|
17
16
|
} from 'react-native';
|
|
17
|
+
import Animated, {
|
|
18
|
+
useAnimatedStyle,
|
|
19
|
+
useSharedValue,
|
|
20
|
+
withTiming,
|
|
21
|
+
} from 'react-native-reanimated';
|
|
18
22
|
import { Colors } from '../../Consts';
|
|
19
23
|
import { Icon } from '../../Icon';
|
|
20
24
|
import { exportFontFamily, Text } from '../../Text';
|
|
@@ -35,11 +39,16 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
35
39
|
|
|
36
40
|
const opacityValue = 0.3;
|
|
37
41
|
const scaleValue = 0.97;
|
|
38
|
-
const opacity =
|
|
39
|
-
const scale =
|
|
42
|
+
const opacity = useSharedValue(opacityValue);
|
|
43
|
+
const scale = useSharedValue(scaleValue);
|
|
40
44
|
const screenName = screen?.name || screen?.type?.name || 'Invalid';
|
|
41
45
|
const { isBackgroundToForeground } = useAppState();
|
|
42
46
|
|
|
47
|
+
const tabAnimatedStyle = useAnimatedStyle(() => ({
|
|
48
|
+
opacity: opacity.value,
|
|
49
|
+
transform: [{ scale: scale.value }],
|
|
50
|
+
}));
|
|
51
|
+
|
|
43
52
|
const onScreenNavigated = (pre: string, current: string) => {
|
|
44
53
|
if (!isBackgroundToForeground) {
|
|
45
54
|
const data: any = {
|
|
@@ -69,18 +78,8 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
69
78
|
useFocusEffect(
|
|
70
79
|
React.useCallback(
|
|
71
80
|
() => {
|
|
72
|
-
|
|
73
|
-
|
|
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();
|
|
81
|
+
opacity.value = withTiming(1, { duration: 200 });
|
|
82
|
+
scale.value = withTiming(1, { duration: 200 });
|
|
84
83
|
|
|
85
84
|
setTimeout(() => {
|
|
86
85
|
navigator?.maxApi?.getDataObserver?.(
|
|
@@ -96,18 +95,8 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
96
95
|
|
|
97
96
|
return () => {
|
|
98
97
|
if (navigation.getState().index !== route?.params.index) {
|
|
99
|
-
|
|
100
|
-
|
|
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();
|
|
98
|
+
opacity.value = withTiming(opacityValue, { duration: 200 });
|
|
99
|
+
scale.value = withTiming(scaleValue, { duration: 200 });
|
|
111
100
|
}
|
|
112
101
|
};
|
|
113
102
|
},
|
|
@@ -147,15 +136,7 @@ const TabScreen: React.FC<any> = ({ route, navigation }) => {
|
|
|
147
136
|
|
|
148
137
|
if (nested) {
|
|
149
138
|
return (
|
|
150
|
-
<Animated.View
|
|
151
|
-
style={[
|
|
152
|
-
styles.container,
|
|
153
|
-
{
|
|
154
|
-
opacity,
|
|
155
|
-
transform: [{ scale }],
|
|
156
|
-
},
|
|
157
|
-
]}
|
|
158
|
-
>
|
|
139
|
+
<Animated.View style={[styles.container, tabAnimatedStyle]}>
|
|
159
140
|
<Stack.Navigator
|
|
160
141
|
screenOptions={{
|
|
161
142
|
headerStyle: {
|
|
@@ -228,10 +209,15 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
228
209
|
const dimensions = useWindowDimensions();
|
|
229
210
|
const insets = useSafeAreaInsets();
|
|
230
211
|
const initialIndex = tabs.findIndex(i => i.name === initialRouteName);
|
|
231
|
-
const indicatorAnimated =
|
|
232
|
-
const activeIndex = useRef(initialIndex > 0 ? initialIndex : 0);
|
|
212
|
+
const indicatorAnimated = useSharedValue(0);
|
|
213
|
+
const activeIndex = React.useRef(initialIndex > 0 ? initialIndex : 0);
|
|
233
214
|
const itemWidth = dimensions.width / tabs.length;
|
|
234
215
|
|
|
216
|
+
const indicatorStyle = useAnimatedStyle(() => ({
|
|
217
|
+
width: itemWidth,
|
|
218
|
+
transform: [{ translateX: indicatorAnimated.value }],
|
|
219
|
+
}));
|
|
220
|
+
|
|
235
221
|
useLayoutEffect(() => {
|
|
236
222
|
navigation?.setOptions({
|
|
237
223
|
headerShown: false,
|
|
@@ -241,20 +227,16 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
241
227
|
}, [navigation]);
|
|
242
228
|
|
|
243
229
|
useEffect(() => {
|
|
244
|
-
|
|
245
|
-
toValue: itemWidth * activeIndex.current,
|
|
246
|
-
useNativeDriver: true,
|
|
230
|
+
indicatorAnimated.value = withTiming(itemWidth * activeIndex.current, {
|
|
247
231
|
duration: 200,
|
|
248
|
-
})
|
|
249
|
-
}, [itemWidth]);
|
|
232
|
+
});
|
|
233
|
+
}, [itemWidth, indicatorAnimated]);
|
|
250
234
|
|
|
251
235
|
const onFocus = (e: any) => {
|
|
252
236
|
activeIndex.current = tabs.findIndex(i => e.target.includes(i.name));
|
|
253
|
-
|
|
254
|
-
toValue: itemWidth * activeIndex.current,
|
|
255
|
-
useNativeDriver: true,
|
|
237
|
+
indicatorAnimated.value = withTiming(itemWidth * activeIndex.current, {
|
|
256
238
|
duration: 200,
|
|
257
|
-
})
|
|
239
|
+
});
|
|
258
240
|
};
|
|
259
241
|
|
|
260
242
|
const handler: {
|
|
@@ -294,13 +276,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
294
276
|
]}
|
|
295
277
|
>
|
|
296
278
|
<Animated.View
|
|
297
|
-
style={[
|
|
298
|
-
styles.indicatorContainer,
|
|
299
|
-
{
|
|
300
|
-
width: itemWidth,
|
|
301
|
-
transform: [{ translateX: indicatorAnimated.current }],
|
|
302
|
-
},
|
|
303
|
-
]}
|
|
279
|
+
style={[styles.indicatorContainer, indicatorStyle]}
|
|
304
280
|
>
|
|
305
281
|
<View
|
|
306
282
|
style={[
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { FC, useContext } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Platform, StyleSheet } from 'react-native';
|
|
3
|
+
import Animated, {
|
|
4
|
+
Extrapolation,
|
|
5
|
+
interpolate,
|
|
6
|
+
useAnimatedStyle,
|
|
7
|
+
type SharedValue,
|
|
8
|
+
} from 'react-native-reanimated';
|
|
3
9
|
import { Image } from '../../Image';
|
|
4
10
|
import { Colors } from '../../Consts';
|
|
5
11
|
import { ApplicationContext } from '../../Context';
|
|
@@ -8,16 +14,26 @@ type BackgroundImageViewProps = {
|
|
|
8
14
|
useShadowHeader: boolean;
|
|
9
15
|
headerBackground?: string;
|
|
10
16
|
heightHeader: number | `${number}%`;
|
|
11
|
-
|
|
17
|
+
animatedValue: SharedValue<number>;
|
|
12
18
|
};
|
|
13
19
|
|
|
14
20
|
const BackgroundImageView: FC<BackgroundImageViewProps> = ({
|
|
15
21
|
useShadowHeader = true,
|
|
16
22
|
headerBackground = null,
|
|
17
23
|
heightHeader,
|
|
18
|
-
|
|
24
|
+
animatedValue,
|
|
19
25
|
}) => {
|
|
20
26
|
const { theme } = useContext(ApplicationContext);
|
|
27
|
+
|
|
28
|
+
const opacityStyle = useAnimatedStyle(() => ({
|
|
29
|
+
opacity: interpolate(
|
|
30
|
+
animatedValue.value,
|
|
31
|
+
[0, 52],
|
|
32
|
+
[0, 1],
|
|
33
|
+
Extrapolation.CLAMP,
|
|
34
|
+
),
|
|
35
|
+
}));
|
|
36
|
+
|
|
21
37
|
if (Platform.OS === 'android') {
|
|
22
38
|
return (
|
|
23
39
|
<Animated.View
|
|
@@ -27,8 +43,8 @@ const BackgroundImageView: FC<BackgroundImageViewProps> = ({
|
|
|
27
43
|
{
|
|
28
44
|
height: heightHeader,
|
|
29
45
|
backgroundColor: theme.colors.background.surface,
|
|
30
|
-
opacity: opacityBackground,
|
|
31
46
|
},
|
|
47
|
+
opacityStyle,
|
|
32
48
|
]}
|
|
33
49
|
>
|
|
34
50
|
{headerBackground && (
|
|
@@ -51,8 +67,8 @@ const BackgroundImageView: FC<BackgroundImageViewProps> = ({
|
|
|
51
67
|
{
|
|
52
68
|
height: heightHeader,
|
|
53
69
|
backgroundColor: theme.colors.background.surface,
|
|
54
|
-
opacity: opacityBackground,
|
|
55
70
|
},
|
|
71
|
+
opacityStyle,
|
|
56
72
|
]}
|
|
57
73
|
/>
|
|
58
74
|
<Animated.View
|
|
@@ -60,8 +76,8 @@ const BackgroundImageView: FC<BackgroundImageViewProps> = ({
|
|
|
60
76
|
styles.hidden,
|
|
61
77
|
{
|
|
62
78
|
height: heightHeader,
|
|
63
|
-
opacity: opacityBackground,
|
|
64
79
|
},
|
|
80
|
+
opacityStyle,
|
|
65
81
|
]}
|
|
66
82
|
>
|
|
67
83
|
{headerBackground && (
|
|
@@ -1,46 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import Animated, {
|
|
3
|
+
Extrapolation,
|
|
4
|
+
interpolate,
|
|
5
|
+
useAnimatedStyle,
|
|
6
|
+
} from 'react-native-reanimated';
|
|
2
7
|
import { type HeaderAnimatedProps } from '../types';
|
|
3
8
|
import React from 'react';
|
|
4
9
|
import { Image } from '../../Image';
|
|
5
10
|
import { Colors } from '../../Consts';
|
|
6
11
|
|
|
7
|
-
/**
|
|
8
|
-
* default header banner for header animated
|
|
9
|
-
*/
|
|
10
12
|
const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
11
13
|
animatedValue,
|
|
12
14
|
image,
|
|
13
15
|
useScale = true,
|
|
14
16
|
children,
|
|
15
17
|
}) => {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
19
|
+
const scale = useScale
|
|
20
|
+
? interpolate(
|
|
21
|
+
animatedValue.value,
|
|
22
|
+
[-300, 0, 300],
|
|
23
|
+
[4, 1, 1],
|
|
24
|
+
Extrapolation.CLAMP,
|
|
25
|
+
)
|
|
26
|
+
: 1;
|
|
27
|
+
const opacity = interpolate(
|
|
28
|
+
animatedValue.value,
|
|
29
|
+
[0, 150, 300],
|
|
30
|
+
[1, 0.5, 0],
|
|
31
|
+
Extrapolation.CLAMP,
|
|
32
|
+
);
|
|
33
|
+
const translateY = interpolate(
|
|
34
|
+
animatedValue.value,
|
|
35
|
+
[-300, 0],
|
|
36
|
+
[-80, -2],
|
|
37
|
+
Extrapolation.CLAMP,
|
|
38
|
+
);
|
|
39
|
+
return {
|
|
40
|
+
opacity,
|
|
41
|
+
transform: [{ scale }, { translateY }],
|
|
42
|
+
};
|
|
32
43
|
});
|
|
33
44
|
|
|
34
45
|
return (
|
|
35
|
-
<Animated.View
|
|
36
|
-
style={[
|
|
37
|
-
styles.container,
|
|
38
|
-
{
|
|
39
|
-
opacity: opacity,
|
|
40
|
-
transform: [{ scale }, { translateY }],
|
|
41
|
-
},
|
|
42
|
-
]}
|
|
43
|
-
>
|
|
46
|
+
<Animated.View style={[styles.container, animatedStyle]}>
|
|
44
47
|
{children ?? (
|
|
45
48
|
<Image
|
|
46
49
|
source={{
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import LinearGradient from 'react-native-linear-gradient';
|
|
2
|
-
import {
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import React, { useContext } from 'react';
|
|
4
|
+
import Animated, { useSharedValue } from 'react-native-reanimated';
|
|
4
5
|
import { HeaderBackgroundProps } from '../types';
|
|
5
6
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
6
7
|
import { Colors, Styles } from '../../Consts';
|
|
7
8
|
import { Image } from '../../Image';
|
|
8
9
|
import BackgroundImageView from './BackgroundImageView';
|
|
9
10
|
|
|
10
|
-
const LinearGradientAnimated = Animated.createAnimatedComponent(LinearGradient);
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* header background for default
|
|
14
|
-
*/
|
|
15
11
|
const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
16
|
-
animatedValue
|
|
12
|
+
animatedValue,
|
|
17
13
|
useGradient = true,
|
|
18
14
|
useShadowHeader = true,
|
|
19
15
|
gradientColor: customGradientColor,
|
|
@@ -23,37 +19,35 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
23
19
|
const context = useContext<any>(MiniAppContext);
|
|
24
20
|
const gradientColor = customGradientColor ?? theme.colors.gradient;
|
|
25
21
|
const headerImage = headerBackground ?? theme.assets?.headerBackground;
|
|
22
|
+
const fallback = useSharedValue(0);
|
|
23
|
+
const sv = animatedValue ?? fallback;
|
|
26
24
|
|
|
27
|
-
const showBaseLineDebug = context?.
|
|
28
|
-
|
|
29
|
-
const opacityBackground = animatedValue?.interpolate({
|
|
30
|
-
inputRange: [0, 52],
|
|
31
|
-
outputRange: [0, 1],
|
|
32
|
-
extrapolate: 'clamp',
|
|
33
|
-
});
|
|
25
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
34
26
|
|
|
35
27
|
return (
|
|
36
28
|
<View style={[Styles.flex, showBaseLineDebug && styles.debugBaseLine]}>
|
|
37
29
|
<BackgroundImageView
|
|
38
30
|
useShadowHeader={useShadowHeader}
|
|
39
31
|
heightHeader={'100%'}
|
|
40
|
-
|
|
32
|
+
animatedValue={sv}
|
|
41
33
|
headerBackground={headerImage}
|
|
42
34
|
/>
|
|
43
35
|
<View style={styles.gradientContainer}>
|
|
44
36
|
{useGradient && !!gradientColor && (
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
37
|
+
<Animated.View style={styles.extendedHeader}>
|
|
38
|
+
<LinearGradient
|
|
39
|
+
colors={[gradientColor, gradientColor + '00']}
|
|
40
|
+
style={StyleSheet.absoluteFill}
|
|
41
|
+
>
|
|
42
|
+
{!!headerImage && (
|
|
43
|
+
<Image
|
|
44
|
+
style={styles.headerBackground}
|
|
45
|
+
source={{ uri: headerImage }}
|
|
46
|
+
loading={false}
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
</LinearGradient>
|
|
50
|
+
</Animated.View>
|
|
57
51
|
)}
|
|
58
52
|
</View>
|
|
59
53
|
</View>
|