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