@momo-kits/foundation 0.161.1-beta.2 → 0.161.2-beta.1
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 +21 -25
- package/Application/ScaleSizeProvider.tsx +16 -0
- package/Application/WidgetContainer.tsx +7 -18
- 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 +13 -3
- 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 +10 -4
- package/Layout/FloatingButton.tsx +59 -59
- 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 +32 -24
- 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
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import React, { Ref, useContext
|
|
1
|
+
import React, { Ref, useContext } from 'react';
|
|
2
2
|
import LinearGradient from 'react-native-linear-gradient';
|
|
3
|
+
import { Dimensions, Platform, StyleSheet, View } from 'react-native';
|
|
4
|
+
import Animated, {
|
|
5
|
+
Extrapolation,
|
|
6
|
+
interpolate,
|
|
7
|
+
useAnimatedStyle,
|
|
8
|
+
useSharedValue,
|
|
9
|
+
type SharedValue,
|
|
10
|
+
} from 'react-native-reanimated';
|
|
3
11
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
4
|
-
import { Animated, Dimensions, Platform, StyleSheet, View } from 'react-native';
|
|
5
12
|
import { HeaderType } from '../../Layout/types';
|
|
6
13
|
import { InputRef, InputSearch } from '../../Input';
|
|
7
14
|
import Navigation from '../Navigation';
|
|
@@ -14,15 +21,10 @@ const SCREEN_PADDING = 12;
|
|
|
14
21
|
const BACK_WIDTH = 28;
|
|
15
22
|
|
|
16
23
|
const { width: screenWidth } = Dimensions.get('window');
|
|
17
|
-
const LinearGradientAnimated = Animated.createAnimatedComponent(LinearGradient);
|
|
18
24
|
|
|
19
|
-
/**
|
|
20
|
-
* Header extended with background image
|
|
21
|
-
* @constructor
|
|
22
|
-
*/
|
|
23
25
|
const HeaderExtendHeader: React.FC<{
|
|
24
26
|
headerType?: HeaderType;
|
|
25
|
-
animatedValue:
|
|
27
|
+
animatedValue: SharedValue<number>;
|
|
26
28
|
heightHeader: number;
|
|
27
29
|
headerRightWidth: number;
|
|
28
30
|
inputSearchProps?: SearchHeaderProps;
|
|
@@ -38,118 +40,132 @@ const HeaderExtendHeader: React.FC<{
|
|
|
38
40
|
headerRightWidth = 73,
|
|
39
41
|
inputSearchProps,
|
|
40
42
|
inputSearchRef,
|
|
41
|
-
useShadowHeader = true,
|
|
43
|
+
useShadowHeader: useShadowHeaderProp = true,
|
|
42
44
|
gradientColor: customGradientColor,
|
|
43
45
|
headerBackground: customBackground,
|
|
44
46
|
}) => {
|
|
45
47
|
const { theme } = useContext(ApplicationContext);
|
|
46
48
|
const context = useContext<any>(MiniAppContext);
|
|
47
|
-
const
|
|
49
|
+
const fallback = useSharedValue(0);
|
|
50
|
+
const sv = animatedValue ?? fallback;
|
|
48
51
|
const gradientColor = customGradientColor ?? theme.colors.gradient;
|
|
49
52
|
const headerBackground = customBackground ?? theme.assets?.headerBackground;
|
|
50
53
|
const leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
outputRange: [0, 1],
|
|
57
|
-
extrapolate: 'clamp',
|
|
58
|
-
});
|
|
59
|
-
const opacityGradient = animatedValue?.interpolate({
|
|
60
|
-
inputRange: [0, 52],
|
|
61
|
-
outputRange: [1, 0],
|
|
62
|
-
extrapolate: 'clamp',
|
|
63
|
-
});
|
|
55
|
+
let useShadowHeader = useShadowHeaderProp;
|
|
56
|
+
if (inputSearchProps && Platform.OS === 'android') {
|
|
57
|
+
useShadowHeader = false;
|
|
58
|
+
}
|
|
64
59
|
|
|
65
|
-
|
|
66
|
-
const listener = animatedValue.addListener(({ value }) => {
|
|
67
|
-
animated.current.setValue(value);
|
|
68
|
-
});
|
|
69
|
-
return () => {
|
|
70
|
-
animatedValue?.removeListener(listener);
|
|
71
|
-
};
|
|
72
|
-
}, [animatedValue]);
|
|
60
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
73
61
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
62
|
+
const heightStyle = useAnimatedStyle(() => ({
|
|
63
|
+
height: interpolate(
|
|
64
|
+
sv.value,
|
|
65
|
+
[0, 100],
|
|
66
|
+
[heightHeader + 52, heightHeader],
|
|
67
|
+
Extrapolation.CLAMP,
|
|
68
|
+
),
|
|
69
|
+
}));
|
|
79
70
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
extrapolate: 'clamp',
|
|
84
|
-
});
|
|
71
|
+
const gradientOpacityStyle = useAnimatedStyle(() => ({
|
|
72
|
+
opacity: interpolate(sv.value, [0, 52], [1, 0], Extrapolation.CLAMP),
|
|
73
|
+
}));
|
|
85
74
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
75
|
+
const searchTranslateStyle = useAnimatedStyle(() => ({
|
|
76
|
+
transform: [
|
|
77
|
+
{
|
|
78
|
+
translateX: interpolate(
|
|
79
|
+
sv.value,
|
|
80
|
+
[0, 100],
|
|
81
|
+
[SCREEN_PADDING, leftPosition],
|
|
82
|
+
Extrapolation.CLAMP,
|
|
83
|
+
),
|
|
84
|
+
},
|
|
91
85
|
],
|
|
92
|
-
|
|
86
|
+
width: interpolate(
|
|
87
|
+
sv.value,
|
|
88
|
+
[0, 100],
|
|
89
|
+
[
|
|
90
|
+
screenWidth - SCREEN_PADDING * 2,
|
|
91
|
+
screenWidth - leftPosition - 12 - headerRightWidth,
|
|
92
|
+
],
|
|
93
|
+
Extrapolation.CLAMP,
|
|
94
|
+
),
|
|
95
|
+
}));
|
|
96
|
+
|
|
97
|
+
const searchBackgroundStyle = useAnimatedStyle(() => {
|
|
98
|
+
const t = Math.min(Math.max(sv.value / 100, 0), 1);
|
|
99
|
+
return { backgroundColor: t === 0
|
|
100
|
+
? theme.colors.background.surface
|
|
101
|
+
: theme.colors.background.default };
|
|
93
102
|
});
|
|
94
103
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
const extendedHeightStyle = useAnimatedStyle(() => ({
|
|
105
|
+
height: interpolate(
|
|
106
|
+
sv.value,
|
|
107
|
+
[0, 100],
|
|
108
|
+
[heightHeader + 52, heightHeader],
|
|
109
|
+
Extrapolation.CLAMP,
|
|
110
|
+
),
|
|
111
|
+
}));
|
|
98
112
|
|
|
99
113
|
if (inputSearchProps) {
|
|
100
114
|
return (
|
|
101
115
|
<View style={[{ zIndex: 0 }, showBaseLineDebug && styles.debugBaseLine]}>
|
|
102
|
-
<Animated.View style={
|
|
116
|
+
<Animated.View style={heightStyle} />
|
|
103
117
|
<BackgroundImageView
|
|
104
118
|
useShadowHeader={useShadowHeader}
|
|
105
119
|
heightHeader={heightHeader}
|
|
106
|
-
|
|
120
|
+
animatedValue={sv}
|
|
107
121
|
headerBackground={headerBackground}
|
|
108
122
|
/>
|
|
109
123
|
<Animated.View
|
|
110
124
|
style={[
|
|
111
125
|
styles.headerBox,
|
|
112
|
-
|
|
126
|
+
headerType === 'extended'
|
|
127
|
+
? heightStyle
|
|
128
|
+
: { height: heightHeader },
|
|
113
129
|
]}
|
|
114
130
|
>
|
|
115
131
|
{!!gradientColor && (
|
|
116
|
-
<
|
|
117
|
-
|
|
118
|
-
style={[styles.extendedHeader, { opacity: opacityGradient }]}
|
|
132
|
+
<Animated.View
|
|
133
|
+
style={[styles.extendedHeader, gradientOpacityStyle]}
|
|
119
134
|
>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
<LinearGradient
|
|
136
|
+
colors={[gradientColor, gradientColor + '00']}
|
|
137
|
+
style={StyleSheet.absoluteFill}
|
|
138
|
+
>
|
|
139
|
+
{!!theme.assets?.headerBackground && (
|
|
140
|
+
<Image
|
|
141
|
+
style={styles.headerBackground}
|
|
142
|
+
source={{ uri: theme.assets?.headerBackground }}
|
|
143
|
+
loading={false}
|
|
144
|
+
/>
|
|
145
|
+
)}
|
|
146
|
+
</LinearGradient>
|
|
147
|
+
</Animated.View>
|
|
128
148
|
)}
|
|
129
149
|
</Animated.View>
|
|
130
150
|
<Animated.View
|
|
131
|
-
style={
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
151
|
+
style={[
|
|
152
|
+
{
|
|
153
|
+
justifyContent: 'flex-end',
|
|
154
|
+
position: 'absolute',
|
|
155
|
+
zIndex: 2,
|
|
156
|
+
},
|
|
157
|
+
heightStyle,
|
|
158
|
+
]}
|
|
137
159
|
>
|
|
138
160
|
<Animated.View
|
|
139
|
-
style={{
|
|
140
|
-
transform: [{ translateX }],
|
|
141
|
-
marginVertical: Spacing.S,
|
|
142
|
-
width: animated.current.interpolate({
|
|
143
|
-
inputRange: [0, 100],
|
|
144
|
-
outputRange: [
|
|
145
|
-
screenWidth - SCREEN_PADDING * 2,
|
|
146
|
-
screenWidth - leftPosition - 12 - headerRightWidth,
|
|
147
|
-
],
|
|
148
|
-
extrapolate: 'clamp',
|
|
149
|
-
}),
|
|
150
|
-
}}
|
|
161
|
+
style={[{ marginVertical: Spacing.S }, searchTranslateStyle]}
|
|
151
162
|
>
|
|
152
|
-
<Animated.View
|
|
163
|
+
<Animated.View
|
|
164
|
+
style={[
|
|
165
|
+
{ borderRadius: Radius.XL },
|
|
166
|
+
searchBackgroundStyle,
|
|
167
|
+
]}
|
|
168
|
+
>
|
|
153
169
|
<InputSearch
|
|
154
170
|
{...inputSearchProps}
|
|
155
171
|
ref={inputSearchRef}
|
|
@@ -169,22 +185,26 @@ const HeaderExtendHeader: React.FC<{
|
|
|
169
185
|
<BackgroundImageView
|
|
170
186
|
useShadowHeader={useShadowHeader}
|
|
171
187
|
heightHeader={heightHeader}
|
|
172
|
-
|
|
188
|
+
animatedValue={sv}
|
|
173
189
|
headerBackground={headerBackground}
|
|
174
190
|
/>
|
|
175
191
|
{!!gradientColor && (
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
style={[styles.extendedHeader, { opacity: opacityGradient }]}
|
|
192
|
+
<Animated.View
|
|
193
|
+
style={[styles.extendedHeader, gradientOpacityStyle, extendedHeightStyle]}
|
|
179
194
|
>
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
195
|
+
<LinearGradient
|
|
196
|
+
colors={[gradientColor, gradientColor + '00']}
|
|
197
|
+
style={StyleSheet.absoluteFill}
|
|
198
|
+
>
|
|
199
|
+
{!!headerBackground && (
|
|
200
|
+
<Image
|
|
201
|
+
style={styles.headerBackground}
|
|
202
|
+
source={{ uri: headerBackground }}
|
|
203
|
+
loading={false}
|
|
204
|
+
/>
|
|
205
|
+
)}
|
|
206
|
+
</LinearGradient>
|
|
207
|
+
</Animated.View>
|
|
188
208
|
)}
|
|
189
209
|
<View style={{ height: heightHeader }} />
|
|
190
210
|
</View>
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
2
|
import {
|
|
3
|
-
Animated,
|
|
4
3
|
Dimensions,
|
|
5
4
|
StyleSheet,
|
|
6
5
|
TouchableOpacity,
|
|
7
6
|
View,
|
|
8
7
|
} from 'react-native';
|
|
8
|
+
import Animated, {
|
|
9
|
+
Extrapolation,
|
|
10
|
+
interpolate,
|
|
11
|
+
useAnimatedStyle,
|
|
12
|
+
type SharedValue,
|
|
13
|
+
} from 'react-native-reanimated';
|
|
9
14
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
10
15
|
import { exportFontFamily, Text, useScaleSize } from '../../Text';
|
|
11
16
|
import { Colors, Radius, Spacing, Styles } from '../../Consts';
|
|
@@ -18,21 +23,45 @@ import { Image } from '../../Image';
|
|
|
18
23
|
import { Icon } from '../../Icon';
|
|
19
24
|
import { Skeleton } from '../../Skeleton';
|
|
20
25
|
|
|
26
|
+
type HeaderTitleInterpolate = {
|
|
27
|
+
inputRange: number[];
|
|
28
|
+
outputRange: number[];
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type HeaderTitleExtraProps = {
|
|
32
|
+
animatedValue?: SharedValue<number>;
|
|
33
|
+
interpolate?: HeaderTitleInterpolate;
|
|
34
|
+
tintColor?: string;
|
|
35
|
+
children?: React.ReactNode;
|
|
36
|
+
};
|
|
37
|
+
|
|
21
38
|
/**
|
|
22
39
|
* default header title used for nav
|
|
23
40
|
*/
|
|
24
|
-
const HeaderTitle: React.FC<any> = props => {
|
|
41
|
+
const HeaderTitle: React.FC<HeaderTitleExtraProps & { [key: string]: any }> = props => {
|
|
25
42
|
const context = useContext<any>(MiniAppContext);
|
|
26
43
|
|
|
27
|
-
const showBaseLineDebug = context?.
|
|
44
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
28
45
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
46
|
+
const interpolateConfig = props.interpolate ?? {
|
|
47
|
+
inputRange: [0, 200],
|
|
48
|
+
outputRange: [0, 1],
|
|
49
|
+
};
|
|
50
|
+
const animatedValue = props.animatedValue;
|
|
51
|
+
|
|
52
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
53
|
+
if (!animatedValue) {
|
|
54
|
+
return { opacity: 1 };
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
opacity: interpolate(
|
|
58
|
+
animatedValue.value,
|
|
59
|
+
interpolateConfig.inputRange,
|
|
60
|
+
interpolateConfig.outputRange,
|
|
61
|
+
Extrapolation.CLAMP,
|
|
62
|
+
),
|
|
63
|
+
};
|
|
64
|
+
});
|
|
36
65
|
|
|
37
66
|
return (
|
|
38
67
|
<View
|
|
@@ -57,9 +86,9 @@ const HeaderTitle: React.FC<any> = props => {
|
|
|
57
86
|
},
|
|
58
87
|
{
|
|
59
88
|
fontFamily: exportFontFamily('bold', 'action_xs_bold'),
|
|
60
|
-
opacity,
|
|
61
89
|
color: props.tintColor,
|
|
62
90
|
},
|
|
91
|
+
animatedStyle,
|
|
63
92
|
]}
|
|
64
93
|
numberOfLines={1}
|
|
65
94
|
/>
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { Colors, Radius, Spacing, Styles } from '../../Consts';
|
|
2
2
|
import { InputRef, InputSearch } from '../../Input';
|
|
3
3
|
import {
|
|
4
|
-
Animated,
|
|
5
4
|
Dimensions,
|
|
6
5
|
StyleSheet,
|
|
7
6
|
TouchableOpacity,
|
|
8
7
|
View,
|
|
9
8
|
} from 'react-native';
|
|
10
|
-
import
|
|
9
|
+
import Animated, {
|
|
10
|
+
useAnimatedStyle,
|
|
11
|
+
useSharedValue,
|
|
12
|
+
} from 'react-native-reanimated';
|
|
13
|
+
import React, { useContext } from 'react';
|
|
11
14
|
import { SearchHeaderProps } from '../types';
|
|
12
15
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
13
16
|
import { Text } from '../../Text';
|
|
@@ -28,28 +31,18 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
28
31
|
const BACK_WIDTH = 28;
|
|
29
32
|
const { width: screenWidth } = Dimensions.get('window');
|
|
30
33
|
|
|
31
|
-
const
|
|
34
|
+
const fallback = useSharedValue(0);
|
|
35
|
+
const sv = animatedValue ?? fallback;
|
|
32
36
|
const leftPosition = props?.leftPosition ?? BACK_WIDTH + 20;
|
|
33
37
|
const headerRightWidth = props?.headerRightWidth ?? 73;
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
animatedValue?.removeListener(listener);
|
|
42
|
-
}
|
|
39
|
+
const backgroundStyle = useAnimatedStyle(() => {
|
|
40
|
+
const t = Math.min(Math.max(sv.value / 100, 0), 1);
|
|
41
|
+
return {
|
|
42
|
+
backgroundColor: t === 0
|
|
43
|
+
? theme.colors.background.surface
|
|
44
|
+
: theme.colors.background.default,
|
|
43
45
|
};
|
|
44
|
-
}, [animatedValue]);
|
|
45
|
-
|
|
46
|
-
const backgroundColor = animated.current?.interpolate({
|
|
47
|
-
inputRange: [0, 100],
|
|
48
|
-
outputRange: [
|
|
49
|
-
theme.colors.background.surface,
|
|
50
|
-
theme.colors.background.default,
|
|
51
|
-
],
|
|
52
|
-
extrapolate: 'clamp',
|
|
53
46
|
});
|
|
54
47
|
|
|
55
48
|
const goBack = () => {
|
|
@@ -77,7 +70,7 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
77
70
|
return true;
|
|
78
71
|
};
|
|
79
72
|
|
|
80
|
-
const showBaseLineDebug = context?.
|
|
73
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
81
74
|
|
|
82
75
|
return (
|
|
83
76
|
<View
|
|
@@ -91,7 +84,9 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
|
|
|
91
84
|
},
|
|
92
85
|
]}
|
|
93
86
|
>
|
|
94
|
-
<Animated.View
|
|
87
|
+
<Animated.View
|
|
88
|
+
style={[{ borderRadius: Radius.XL }, backgroundStyle]}
|
|
89
|
+
>
|
|
95
90
|
<InputSearch
|
|
96
91
|
ref={ref}
|
|
97
92
|
{...props}
|
|
@@ -16,6 +16,7 @@ import { DeviceEventEmitter } from 'react-native';
|
|
|
16
16
|
import StackScreen from './StackScreen';
|
|
17
17
|
import ModalScreen from './ModalScreen';
|
|
18
18
|
import Navigator from './Navigator';
|
|
19
|
+
import ScaleSizeProvider from './ScaleSizeProvider';
|
|
19
20
|
import { getModalOptions, getStackOptions } from './utils';
|
|
20
21
|
import { NavigationContainerProps } from './types';
|
|
21
22
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
@@ -35,44 +36,39 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
35
36
|
maxApi,
|
|
36
37
|
initialParams,
|
|
37
38
|
localize = new Localize({ vi: {}, en: {} }),
|
|
39
|
+
features = {
|
|
40
|
+
enableBottomTabAnimation: true,
|
|
41
|
+
enableHapticDialog: true,
|
|
42
|
+
enableForceFoundationList: false,
|
|
43
|
+
enableHapticBottomTab: true,
|
|
44
|
+
},
|
|
38
45
|
}) => {
|
|
39
46
|
const context = useContext<any>(MiniAppContext);
|
|
40
47
|
const [currentContext, setCurrentContext] = useState<any>({});
|
|
41
|
-
const [allowFontScale, setAllowFontScale] = useState<boolean>(
|
|
42
|
-
context?.designSystemConfig?.allowFontScale ?? true,
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
const sub = maxApi?.observer?.('use_font_scale', (value: boolean) => {
|
|
47
|
-
setAllowFontScale(value ?? true);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return () => {
|
|
51
|
-
sub?.remove?.();
|
|
52
|
-
};
|
|
53
|
-
}, []);
|
|
54
48
|
|
|
55
49
|
const mergedContext = {
|
|
56
50
|
...context,
|
|
57
51
|
...currentContext,
|
|
58
|
-
|
|
59
|
-
...context?.
|
|
60
|
-
|
|
52
|
+
features: {
|
|
53
|
+
...context?.features,
|
|
54
|
+
...features,
|
|
61
55
|
},
|
|
62
56
|
};
|
|
63
57
|
|
|
64
58
|
return (
|
|
65
59
|
<SafeAreaProvider>
|
|
66
60
|
<MiniAppContext.Provider value={mergedContext}>
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
61
|
+
<ScaleSizeProvider scaleSizeMaxRate={mergedContext?.scaleSizeMaxRate}>
|
|
62
|
+
<Navigation
|
|
63
|
+
screen={screen}
|
|
64
|
+
theme={theme}
|
|
65
|
+
options={options}
|
|
66
|
+
maxApi={maxApi}
|
|
67
|
+
setCurrentContext={setCurrentContext}
|
|
68
|
+
initialParams={initialParams}
|
|
69
|
+
localize={localize}
|
|
70
|
+
/>
|
|
71
|
+
</ScaleSizeProvider>
|
|
76
72
|
</MiniAppContext.Provider>
|
|
77
73
|
</SafeAreaProvider>
|
|
78
74
|
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
import { ScaleSizeContext } from '../Context';
|
|
3
|
+
import { ScaleSizeProviderProps } from './types';
|
|
4
|
+
|
|
5
|
+
const ScaleSizeProvider: FC<ScaleSizeProviderProps> = ({
|
|
6
|
+
scaleSizeMaxRate,
|
|
7
|
+
children,
|
|
8
|
+
}) => {
|
|
9
|
+
return (
|
|
10
|
+
<ScaleSizeContext.Provider value={{ scaleSizeMaxRate }}>
|
|
11
|
+
{children}
|
|
12
|
+
</ScaleSizeContext.Provider>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default ScaleSizeProvider;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import React, { useContext,
|
|
1
|
+
import React, { useContext, useRef, useState } from 'react';
|
|
2
2
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
3
3
|
import Navigator from './Navigator';
|
|
4
|
+
import ScaleSizeProvider from './ScaleSizeProvider';
|
|
4
5
|
import { WidgetContainerProps } from './types';
|
|
5
6
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
6
7
|
import Localize from './Localize';
|
|
@@ -42,19 +43,7 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
42
43
|
const isReady = useRef(false);
|
|
43
44
|
const navigator = useRef(new Navigator(navigationRef, isReady, true));
|
|
44
45
|
const [currentContext, setCurrentContext] = useState({});
|
|
45
|
-
const [allowFontScale, setAllowFontScale] = useState<boolean>(
|
|
46
|
-
context?.designSystemConfig?.allowFontScale ?? true,
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
const sub = maxApi?.observer?.('use_font_scale', (value: boolean) => {
|
|
51
|
-
setAllowFontScale(value ?? true);
|
|
52
|
-
});
|
|
53
46
|
|
|
54
|
-
return () => {
|
|
55
|
-
sub?.remove?.();
|
|
56
|
-
};
|
|
57
|
-
}, []);
|
|
58
47
|
let headerBackground = context?.designConfig?.headerBar;
|
|
59
48
|
let headerGradient = theme.colors?.gradient;
|
|
60
49
|
|
|
@@ -82,16 +71,15 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
82
71
|
const mergedContext = {
|
|
83
72
|
...context,
|
|
84
73
|
...currentContext,
|
|
85
|
-
designSystemConfig: {
|
|
86
|
-
...context?.designSystemConfig,
|
|
87
|
-
allowFontScale,
|
|
88
|
-
},
|
|
89
74
|
};
|
|
90
75
|
|
|
91
76
|
return (
|
|
92
|
-
<View style={{ height: height ?? '100%', minHeight:
|
|
77
|
+
<View style={{ height: height ?? '100%', minHeight:1 }}>
|
|
93
78
|
<SafeAreaProvider>
|
|
94
79
|
<MiniAppContext.Provider value={mergedContext}>
|
|
80
|
+
<ScaleSizeProvider
|
|
81
|
+
scaleSizeMaxRate={mergedContext?.scaleSizeMaxRate}
|
|
82
|
+
>
|
|
95
83
|
<ApplicationContext.Provider
|
|
96
84
|
value={{
|
|
97
85
|
navigator: navigator.current,
|
|
@@ -169,6 +157,7 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
169
157
|
</ReactNavigationContainer>
|
|
170
158
|
</NavigationIndependentTree>
|
|
171
159
|
</ApplicationContext.Provider>
|
|
160
|
+
</ScaleSizeProvider>
|
|
172
161
|
</MiniAppContext.Provider>
|
|
173
162
|
</SafeAreaProvider>
|
|
174
163
|
</View>
|
package/Application/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './Components/SearchHeader';
|
|
|
16
16
|
import { exportHeaderTitle, setAutomationID, useComponentId } from './utils';
|
|
17
17
|
import Navigation from './Navigation';
|
|
18
18
|
import Navigator from './Navigator';
|
|
19
|
+
import ScaleSizeProvider from './ScaleSizeProvider';
|
|
19
20
|
import { useTooltipPortal } from './TooltipPortal';
|
|
20
21
|
|
|
21
22
|
export {
|
|
@@ -28,5 +29,6 @@ export {
|
|
|
28
29
|
Navigation,
|
|
29
30
|
Navigator,
|
|
30
31
|
exportHeaderTitle,
|
|
32
|
+
ScaleSizeProvider,
|
|
31
33
|
useTooltipPortal,
|
|
32
34
|
};
|
package/Application/types.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { EventArg } from '@react-navigation/core';
|
|
|
2
2
|
import { StackNavigationOptions } from '@react-navigation/stack';
|
|
3
3
|
import React, { ReactNode } from 'react';
|
|
4
4
|
import {
|
|
5
|
-
Animated,
|
|
6
5
|
TouchableOpacityProps,
|
|
7
6
|
ViewProps,
|
|
8
7
|
ViewStyle,
|
|
9
8
|
} from 'react-native';
|
|
9
|
+
import type { SharedValue } from 'react-native-reanimated';
|
|
10
10
|
import { PopupNotifyProps } from '../Popup/types';
|
|
11
11
|
import { InputRef, InputSearchProps } from '../Input';
|
|
12
12
|
import Navigation from './Navigation';
|
|
@@ -107,6 +107,11 @@ export type Theme = {
|
|
|
107
107
|
};
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
export type ScaleSizeProviderProps = {
|
|
111
|
+
scaleSizeMaxRate?: number;
|
|
112
|
+
children: ViewProps['children'];
|
|
113
|
+
};
|
|
114
|
+
|
|
110
115
|
export type Context = {
|
|
111
116
|
[key: string]: any;
|
|
112
117
|
theme: Theme;
|
|
@@ -153,6 +158,7 @@ export type NavigationContainerProps = {
|
|
|
153
158
|
maxApi: any;
|
|
154
159
|
initialParams?: any;
|
|
155
160
|
localize: LocalizeProps;
|
|
161
|
+
features?: FeatureFlags;
|
|
156
162
|
};
|
|
157
163
|
|
|
158
164
|
export type WidgetContainerProps = {
|
|
@@ -252,7 +258,7 @@ export interface HeaderBackProps extends NavigationButtonProps {
|
|
|
252
258
|
}
|
|
253
259
|
|
|
254
260
|
export type HeaderBackgroundProps = {
|
|
255
|
-
animatedValue?:
|
|
261
|
+
animatedValue?: SharedValue<number>;
|
|
256
262
|
useGradient?: boolean;
|
|
257
263
|
useShadowHeader?: boolean;
|
|
258
264
|
backgroundColor?: string;
|
|
@@ -292,7 +298,7 @@ export type TitleJourneyProps = {
|
|
|
292
298
|
};
|
|
293
299
|
|
|
294
300
|
export interface HeaderAnimatedProps extends ViewProps {
|
|
295
|
-
animatedValue:
|
|
301
|
+
animatedValue: SharedValue<number>;
|
|
296
302
|
image: string;
|
|
297
303
|
useScale?: boolean;
|
|
298
304
|
}
|
|
@@ -336,7 +342,7 @@ export type AnimatedHeader = {
|
|
|
336
342
|
|
|
337
343
|
export interface SearchHeaderProps extends InputSearchProps {
|
|
338
344
|
ref?: React.RefObject<InputRef>;
|
|
339
|
-
animatedValue?:
|
|
345
|
+
animatedValue?: SharedValue<number>;
|
|
340
346
|
headerRightWidth?: 0 | 74 | 110 | number;
|
|
341
347
|
leftPosition?: 12 | 48 | number;
|
|
342
348
|
renderButtons?: () => ReactNode;
|