@momo-kits/foundation 0.89.5-beta.18 → 0.89.6

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.
@@ -120,13 +120,19 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
120
120
  const goBack = () => {
121
121
  const canGoBack = navigator?.ref.current?.canGoBack();
122
122
  if (!canGoBack) {
123
- const currentRoute = navigator?.ref?.current.getCurrentRoute();
124
- navigator?.maxApi?.trackEvent?.('service_icon_clicked', {
123
+ const currentRoute = navigator?.ref?.current?.getCurrentRoute?.();
124
+ const params = {
125
125
  ...context,
126
126
  screen_name: currentRoute?.params?.screen?.name ?? currentRoute?.name,
127
127
  trigger_id: '111154000000000000',
128
128
  icon_name: 'back',
129
+ };
130
+ navigator?.maxApi?.showToastDebug?.({
131
+ appId: context.appId,
132
+ message: 'service_icon_clicked',
133
+ params,
129
134
  });
135
+ navigator?.maxApi?.trackEvent?.('service_icon_clicked', params);
130
136
  }
131
137
  if (canGoBack) {
132
138
  navigator?.ref.current?.goBack();
@@ -284,7 +290,7 @@ const HeaderToolkitAction: React.FC<any> = ({
284
290
  tintColor,
285
291
  pinnedTool,
286
292
  runtimeTools = [],
287
- preventBack,
293
+ preventClose,
288
294
  }) => {
289
295
  const {theme, navigator} = useContext(ApplicationContext);
290
296
  const miniContext = useContext(MiniAppContext);
@@ -331,15 +337,15 @@ const HeaderToolkitAction: React.FC<any> = ({
331
337
  };
332
338
 
333
339
  const onClose = () => {
334
- if (preventBack) {
340
+ if (preventClose) {
335
341
  navigator?.showModal({
336
342
  screen: () => (
337
343
  <PopupNotify
338
- {...preventBack}
344
+ {...preventClose}
339
345
  primary={{
340
- title: preventBack.primary.title,
346
+ title: preventClose.primary.title,
341
347
  onPress: () => {
342
- preventBack?.primary.onPress();
348
+ preventClose?.primary.onPress();
343
349
  navigator?.maxApi?.dispatchFunction?.(
344
350
  'dismiss',
345
351
  undefined,
@@ -415,7 +421,7 @@ const HeaderToolkitAction: React.FC<any> = ({
415
421
  const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
416
422
  animatedValue,
417
423
  image,
418
- onPress,
424
+ children,
419
425
  }) => {
420
426
  const scale = animatedValue.interpolate({
421
427
  inputRange: [-300, 0, 300],
@@ -434,21 +440,21 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
434
440
  });
435
441
 
436
442
  return (
437
- <TouchableOpacity onPress={onPress}>
438
- <Animated.View
439
- style={{
440
- height: 210,
441
- opacity: opacity,
442
- transform: [{scale}, {translateY}],
443
- }}>
443
+ <Animated.View
444
+ style={{
445
+ height: 210,
446
+ opacity: opacity,
447
+ transform: [{scale}, {translateY}],
448
+ }}>
449
+ {children ?? (
444
450
  <Image
445
451
  source={{
446
452
  uri: image,
447
453
  }}
448
454
  style={{width: '100%', height: '100%'}}
449
455
  />
450
- </Animated.View>
451
- </TouchableOpacity>
456
+ )}
457
+ </Animated.View>
452
458
  );
453
459
  };
454
460
 
@@ -1,29 +1,21 @@
1
- import React, {useContext, useEffect, useMemo, useRef, useState} from 'react';
1
+ import React, {useContext, useEffect, useRef} from 'react';
2
2
  import {
3
- Dimensions,
4
- Keyboard,
5
3
  KeyboardAvoidingView,
6
4
  Platform,
7
5
  Pressable,
8
6
  StyleSheet,
7
+ TouchableOpacity,
9
8
  View,
10
9
  } from 'react-native';
10
+ import {Modalize} from 'react-native-modalize';
11
11
  import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
12
- import {
13
- BottomSheetBackdrop,
14
- BottomSheetModal,
15
- BottomSheetView,
16
- } from '@gorhom/bottom-sheet';
12
+
13
+ import {ApplicationContext} from '.';
14
+ import {Radius, Spacing, Styles} from '../Consts';
15
+ import {Icon} from '../Icon';
16
+ import {Text} from '../Text';
17
17
  import Navigation from './Navigation';
18
18
  import {BottomSheetParams, ModalParams} from './types';
19
- import {Radius, Spacing, Styles} from '../Consts';
20
- import {
21
- ApplicationContext,
22
- HeaderRightAction,
23
- NavigationButton,
24
- NavigationContainer,
25
- } from './index';
26
- import {HeaderBackground, HeaderLeft, HeaderTitle} from './Components';
27
19
 
28
20
  const ModalScreen: React.FC<any> = props => {
29
21
  /**
@@ -92,141 +84,88 @@ const Modal: React.FC<ModalParams> = props => {
92
84
  };
93
85
 
94
86
  const BottomSheet: React.FC<BottomSheetParams> = props => {
95
- const insets = useSafeAreaInsets();
96
87
  const {theme, navigator} = useContext(ApplicationContext);
97
- const [keyboardSnap, setKeyboardSnap] = useState(0);
98
- const {screen, options, snapPoint, indicatorColor}: BottomSheetParams =
99
- props.route.params;
100
- const Component = useRef(screen).current;
88
+ const {
89
+ screen: Screen,
90
+ options,
91
+ footerComponent,
92
+ flatListProps,
93
+ }: BottomSheetParams = props.route.params;
94
+
101
95
  const navigation = new Navigation(props.navigation, theme);
96
+
102
97
  const params = {
103
98
  ...props.route.params,
104
99
  navigation,
105
100
  };
106
101
 
107
102
  delete params.screen;
108
-
109
- const snapPoints = useMemo(() => {
110
- if (snapPoint) {
111
- const current = parseInt(snapPoint) + keyboardSnap * 100;
112
- return [`${current}%`];
113
- }
114
- return ['50%', '70%', '90%'];
115
- }, [keyboardSnap]);
116
-
117
- const bottomSheetRef = useRef<any>(null);
118
- const mountedRef = useRef(true);
119
-
120
- let backgroundColor = theme.colors.background.default;
121
- let bottomInset = keyboardSnap * Dimensions.get('window').height;
122
- if (bottomInset > 16) {
123
- bottomInset -= 16;
124
- }
125
- if (options?.surface) {
126
- backgroundColor = theme.colors.background.surface;
127
- }
103
+ const modalizeRef = useRef<Modalize>(null);
128
104
 
129
105
  useEffect(() => {
130
- const keyboardDidShow = Keyboard.addListener('keyboardDidShow', e => {
131
- setKeyboardSnap(
132
- e.endCoordinates.height / Dimensions.get('window').height,
133
- );
134
- bottomSheetRef.current?.expand();
135
- });
136
-
137
- const keyboardDidHide = Keyboard.addListener('keyboardDidHide', () => {
138
- setKeyboardSnap(0);
139
- });
140
-
141
- bottomSheetRef.current?.present();
142
- return () => {
143
- mountedRef.current = false;
144
- keyboardDidShow.remove();
145
- keyboardDidHide.remove();
146
- };
106
+ modalizeRef.current?.open();
147
107
  }, []);
148
108
 
149
- const backdropComponent = (backdropProps: any) => (
150
- <BottomSheetBackdrop
151
- disappearsOnIndex={-1}
152
- appearsOnIndex={0}
153
- {...backdropProps}
154
- />
155
- );
109
+ const handleClose = () => {
110
+ modalizeRef?.current?.close();
111
+ };
156
112
 
157
113
  return (
158
114
  <SafeAreaView style={Styles.flex}>
159
- <BottomSheetModal
160
- ref={bottomSheetRef}
161
- snapPoints={snapPoints}
162
- onDismiss={() => {
163
- if (mountedRef.current) {
164
- navigator?.pop();
165
- }
115
+ <Modalize
116
+ keyboardAvoidingOffset={-20}
117
+ adjustToContentHeight
118
+ closeOnOverlayTap
119
+ closeSnapPointStraightEnabled
120
+ onClosed={() => {
121
+ navigator?.pop();
166
122
  }}
167
- bottomInset={Platform.OS === 'ios' ? bottomInset : 0}
168
- handleComponent={null}
169
- backdropComponent={backdropComponent}>
170
- <BottomSheetView>
171
- <View style={[styles.sheetContainer, {backgroundColor}]}>
172
- <View style={styles.indicatorContainer}>
173
- <View
174
- style={[
175
- styles.indicator,
176
- {backgroundColor: theme.colors.text.disable},
177
- ]}
178
- />
179
- </View>
180
- <NavigationContainer
181
- maxApi={navigator?.maxApi}
182
- theme={{
183
- ...theme,
184
- assets: {...theme.assets, headerBackground: undefined},
185
- }}
186
- screen={props => <Component {...props} {...params} />}
187
- options={{
188
- ...options,
189
- ...{
190
- headerLeft: (props: any) => {
191
- if (props.canGoBack) {
192
- return <HeaderLeft {...props} useBorder={false} />;
193
- }
194
- },
195
- headerTitle: (props: any) => {
196
- return <HeaderTitle {...props} />;
197
- },
198
- headerTintColor: theme.colors.text.default,
199
- headerBackground: () => (
200
- <HeaderBackground backgroundColor={backgroundColor} />
201
- ),
202
- headerTransparent: false,
203
- },
204
- headerTitleAlign: 'center',
205
- headerRight: props => (
206
- <HeaderRightAction>
207
- <NavigationButton
208
- {...props}
209
- icon="24_navigation_close"
210
- useBorder={false}
211
- onPress={() => bottomSheetRef.current?.dismiss()}
212
- />
213
- </HeaderRightAction>
214
- ),
215
- }}
216
- />
217
- <View
218
- style={{
219
- height: Math.min(insets.bottom, 20),
220
- backgroundColor: indicatorColor ?? backgroundColor,
221
- }}
222
- />
223
- </View>
224
- </BottomSheetView>
225
- </BottomSheetModal>
123
+ ref={modalizeRef}
124
+ withHandle={false}
125
+ flatListProps={flatListProps}
126
+ HeaderComponent={headerDefault(
127
+ options?.title ?? options?.customTitle?.title ?? '',
128
+ handleClose,
129
+ )}
130
+ FooterComponent={footerDefault(footerComponent)}>
131
+ <View style={styles.bottomSheetContainer}>
132
+ <Screen {...props} {...params} />
133
+ </View>
134
+ </Modalize>
226
135
  </SafeAreaView>
227
136
  );
228
137
  };
229
138
 
139
+ const headerDefault = (title: string, onClose: () => void) => {
140
+ return (
141
+ <View style={styles.header}>
142
+ <Text
143
+ style={styles.textOption}
144
+ numberOfLines={2}
145
+ typography="header_default_bold">
146
+ {title ?? ''}
147
+ </Text>
148
+ <TouchableOpacity style={styles.buttonClose} onPress={onClose}>
149
+ <Icon source="navigation_close" />
150
+ </TouchableOpacity>
151
+ </View>
152
+ );
153
+ };
154
+
155
+ const footerDefault = (footerComponent: React.ReactNode) => {
156
+ const insets = useSafeAreaInsets();
157
+ if (!footerComponent) return;
158
+ return (
159
+ <View
160
+ style={{
161
+ marginBottom: Math.min(insets.bottom, 21) + Spacing.S,
162
+ paddingHorizontal: 12,
163
+ }}>
164
+ {footerComponent}
165
+ </View>
166
+ );
167
+ };
168
+
230
169
  const styles = StyleSheet.create({
231
170
  container: {flex: 1, flexDirection: 'row'},
232
171
  modalContent: {
@@ -263,6 +202,43 @@ const styles = StyleSheet.create({
263
202
  height: 4,
264
203
  borderRadius: Radius.S,
265
204
  },
205
+ bottomSheetContainer: {
206
+ width: '100%',
207
+ backgroundColor: 'white',
208
+ borderTopRightRadius: 16,
209
+ borderTopLeftRadius: 16,
210
+ },
211
+ header: {
212
+ height: 50,
213
+ width: '100%',
214
+ alignItems: 'center',
215
+ justifyContent: 'center',
216
+ },
217
+ textOption: {
218
+ fontSize: 16,
219
+ color: '#303233',
220
+ textAlign: 'center',
221
+ fontWeight: 'bold',
222
+ paddingHorizontal: 60,
223
+ },
224
+ imageOption: {
225
+ height: 1,
226
+ backgroundColor: '#ebebeb',
227
+ width: '100%',
228
+ position: 'absolute',
229
+ bottom: 1,
230
+ },
231
+ buttonClose: {
232
+ padding: 12,
233
+ position: 'absolute',
234
+ right: 0,
235
+ },
236
+ icon: {
237
+ width: 24,
238
+ height: 24,
239
+ tintColor: '#303233',
240
+ backgroundColor: 'red',
241
+ },
266
242
  });
267
243
 
268
244
  export default ModalScreen;
@@ -1,5 +1,4 @@
1
1
  import React, {useContext, useEffect, useRef, useState} from 'react';
2
- import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
3
2
  import {SafeAreaProvider} from 'react-native-safe-area-context';
4
3
  import {
5
4
  NavigationContainer as ReactNavigationContainer,
@@ -25,8 +24,9 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
25
24
  localization,
26
25
  }) => {
27
26
  const context = useContext(MiniAppContext);
28
- const navigationRef = React.useRef<NavigationContainerRef>(null);
29
- const navigator = useRef(new Navigator(navigationRef));
27
+ const navigationRef = useRef<NavigationContainerRef>(null);
28
+ const isReady = useRef(false);
29
+ const navigator = useRef(new Navigator(navigationRef, isReady));
30
30
  const [showGrid, setShowGrid] = useState(false);
31
31
  const config = useRef<any>();
32
32
 
@@ -67,52 +67,53 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
67
67
 
68
68
  return (
69
69
  <SafeAreaProvider>
70
- <BottomSheetModalProvider>
71
- <ApplicationContext.Provider
72
- value={{
73
- navigator: navigator.current,
74
- config: config.current,
75
- theme,
76
- showGrid,
77
- translate,
78
- }}>
79
- <ReactNavigationContainer
80
- theme={{
81
- ...theme,
82
- colors: {
83
- ...theme.colors,
84
- background: theme.colors.background.default,
85
- card: theme.colors.background.surface,
86
- text: theme.colors.text.default,
87
- border: theme.colors.border.default,
88
- notification: theme.colors.error.primary,
89
- },
90
- }}
91
- ref={navigator.current?.ref}
92
- independent={true}>
93
- <Stack.Navigator initialRouteName="Stack" headerMode="screen">
94
- <Stack.Screen
95
- name="Stack"
96
- component={StackScreen}
97
- initialParams={{screen}}
98
- options={{...getStackOptions(), ...options}}
99
- />
100
- <Stack.Screen
101
- name="Dialog"
102
- component={StackScreen}
103
- options={getDialogOptions()}
104
- initialParams={{screen}}
105
- />
106
- <Stack.Screen
107
- name="Modal"
108
- component={ModalScreen}
109
- options={getModalOptions()}
110
- initialParams={{screen}}
111
- />
112
- </Stack.Navigator>
113
- </ReactNavigationContainer>
114
- </ApplicationContext.Provider>
115
- </BottomSheetModalProvider>
70
+ <ApplicationContext.Provider
71
+ value={{
72
+ navigator: navigator.current,
73
+ config: config.current,
74
+ theme,
75
+ showGrid,
76
+ translate,
77
+ }}>
78
+ <ReactNavigationContainer
79
+ theme={{
80
+ ...theme,
81
+ colors: {
82
+ ...theme.colors,
83
+ background: theme.colors.background.default,
84
+ card: theme.colors.background.surface,
85
+ text: theme.colors.text.default,
86
+ border: theme.colors.border.default,
87
+ notification: theme.colors.error.primary,
88
+ },
89
+ }}
90
+ ref={navigator.current?.ref}
91
+ onReady={() => {
92
+ isReady.current = true;
93
+ }}
94
+ independent={true}>
95
+ <Stack.Navigator initialRouteName="Stack" headerMode="screen">
96
+ <Stack.Screen
97
+ name="Stack"
98
+ component={StackScreen}
99
+ initialParams={{screen}}
100
+ options={{...getStackOptions(), ...options}}
101
+ />
102
+ <Stack.Screen
103
+ name="Dialog"
104
+ component={StackScreen}
105
+ options={getDialogOptions()}
106
+ initialParams={{screen}}
107
+ />
108
+ <Stack.Screen
109
+ name="Modal"
110
+ component={ModalScreen}
111
+ options={getModalOptions()}
112
+ initialParams={{screen}}
113
+ />
114
+ </Stack.Navigator>
115
+ </ReactNavigationContainer>
116
+ </ApplicationContext.Provider>
116
117
  </SafeAreaProvider>
117
118
  );
118
119
  };
@@ -8,13 +8,15 @@ import {
8
8
 
9
9
  class Navigator {
10
10
  ref?: any;
11
+ isReady?: any;
11
12
  toolkitConfig?: HeaderToolkitProps;
12
13
  maxApi?: any;
13
14
  dismissData?: any;
14
15
  toolkitCallback?: (item: any) => void;
15
16
 
16
- constructor(navigation: any) {
17
+ constructor(navigation: any, isReady: any) {
17
18
  this.ref = navigation;
19
+ this.isReady = isReady;
18
20
  }
19
21
 
20
22
  /**
@@ -22,7 +24,9 @@ class Navigator {
22
24
  * @param params
23
25
  */
24
26
  push = (params: ScreenParams) => {
25
- this.ref.current.dispatch(StackActions.push('Stack', params));
27
+ if (this.isReady.current) {
28
+ this.ref.current.dispatch(StackActions.push('Stack', params));
29
+ }
26
30
  };
27
31
 
28
32
  /**
@@ -30,14 +34,18 @@ class Navigator {
30
34
  * @param params
31
35
  */
32
36
  replace = (params: ScreenParams) => {
33
- this.ref.current.dispatch(StackActions.replace('Stack', params));
37
+ if (this.isReady.current) {
38
+ this.ref.current.dispatch(StackActions.replace('Stack', params));
39
+ }
34
40
  };
35
41
  /**
36
42
  * pop to dismiss a screen
37
43
  * @param count
38
44
  */
39
45
  pop = (count?: number) => {
40
- this.ref.current.dispatch(StackActions.pop(count ?? 1));
46
+ if (this.isReady.current) {
47
+ this.ref.current.dispatch(StackActions.pop(count ?? 1));
48
+ }
41
49
  };
42
50
 
43
51
  /**
@@ -45,7 +53,9 @@ class Navigator {
45
53
  * @param params
46
54
  */
47
55
  present = (params: ScreenParams) => {
48
- this.ref.current.dispatch(StackActions.push('Dialog', params));
56
+ if (this.isReady.current) {
57
+ this.ref.current.dispatch(StackActions.push('Dialog', params));
58
+ }
49
59
  };
50
60
 
51
61
  /**
@@ -53,7 +63,9 @@ class Navigator {
53
63
  * @param params
54
64
  */
55
65
  showModal = (params: ModalParams) => {
56
- this.ref.current.dispatch(StackActions.push('Modal', params));
66
+ if (this.isReady.current) {
67
+ this.ref.current.dispatch(StackActions.push('Modal', params));
68
+ }
57
69
  };
58
70
 
59
71
  /**
@@ -61,19 +73,23 @@ class Navigator {
61
73
  * @param params
62
74
  */
63
75
  showBottomSheet = (params: BottomSheetParams) => {
64
- this.ref.current.dispatch(
65
- StackActions.push('Modal', {
66
- ...params,
67
- isBottomSheet: true,
68
- }),
69
- );
76
+ if (this.isReady.current) {
77
+ this.ref.current.dispatch(
78
+ StackActions.push('Modal', {
79
+ ...params,
80
+ isBottomSheet: true,
81
+ }),
82
+ );
83
+ }
70
84
  };
71
85
 
72
86
  /**
73
87
  * pop all screen route
74
88
  */
75
89
  popToTop = () => {
76
- this.ref.current.dispatch(StackActions.popToTop());
90
+ if (this.isReady.current) {
91
+ this.ref.current.dispatch(StackActions.popToTop());
92
+ }
77
93
  };
78
94
 
79
95
  /**
@@ -82,12 +98,14 @@ class Navigator {
82
98
  * @param params
83
99
  */
84
100
  navigate = (name: string, params: any) => {
85
- this.ref.current.dispatch(
86
- CommonActions.navigate({
87
- name,
88
- params,
89
- }),
90
- );
101
+ if (this.isReady.current) {
102
+ this.ref.current.dispatch(
103
+ CommonActions.navigate({
104
+ name,
105
+ params,
106
+ }),
107
+ );
108
+ }
91
109
  };
92
110
 
93
111
  /**
@@ -95,18 +113,20 @@ class Navigator {
95
113
  * @param params
96
114
  */
97
115
  reset = (params: ScreenParams) => {
98
- this.ref.current.dispatch(
99
- CommonActions.reset({
100
- index: 0,
101
- routes: [
102
- {
103
- name: 'Stack',
104
- key: `Stack_${new Date().getTime()}`,
105
- params,
106
- },
107
- ],
108
- }),
109
- );
116
+ if (this.isReady.current) {
117
+ this.ref.current.dispatch(
118
+ CommonActions.reset({
119
+ index: 0,
120
+ routes: [
121
+ {
122
+ name: 'Stack',
123
+ key: `Stack_${new Date().getTime()}`,
124
+ params,
125
+ },
126
+ ],
127
+ }),
128
+ );
129
+ }
110
130
  };
111
131
 
112
132
  /**
@@ -45,17 +45,29 @@ const StackScreen: React.FC<ScreenParams> = props => {
45
45
  pre_screen_name = routes[routesLength - 2]?.params?.screen?.name;
46
46
  }
47
47
 
48
- navigator?.maxApi?.trackEvent?.('service_frame_displayed', {
48
+ const params = {
49
49
  ...tracking,
50
50
  pre_screen_name,
51
51
  trigger_id: '111378000000000000',
52
+ };
53
+ navigator?.maxApi?.trackEvent?.('service_frame_displayed', params);
54
+ navigator?.maxApi?.showToastDebug?.({
55
+ appId: context.appId,
56
+ message: `${Component.name} service_frame_displayed`,
57
+ params,
52
58
  });
53
59
 
54
60
  return props.navigation.addListener('beforeRemove', () => {
55
- navigator?.maxApi?.trackEvent?.('service_icon_clicked', {
61
+ const params = {
56
62
  ...tracking,
57
63
  trigger_id: '111154000000000000',
58
64
  icon_name: 'back',
65
+ };
66
+ navigator?.maxApi?.trackEvent?.('service_icon_clicked', params);
67
+ navigator?.maxApi?.showToastDebug?.({
68
+ appId: context.appId,
69
+ message: `${Component.name} service_icon_clicked`,
70
+ params,
59
71
  });
60
72
  });
61
73
  }, []);
@@ -4,10 +4,8 @@ import {
4
4
  HeaderAnimated,
5
5
  HeaderBackground,
6
6
  HeaderCustom,
7
- HeaderLeft,
8
7
  HeaderRightAction,
9
8
  HeaderTitle,
10
- HeaderToolkitAction,
11
9
  NavigationButton,
12
10
  } from './Components';
13
11
  import BottomTab from './BottomTab';
@@ -32,10 +30,8 @@ export {
32
30
  BottomTab,
33
31
  NavigationButton,
34
32
  HeaderTitle,
35
- HeaderLeft,
36
33
  HeaderBackground,
37
34
  HeaderRightAction,
38
- HeaderToolkitAction,
39
35
  HeaderCustom,
40
36
  HeaderAnimated,
41
37
  };
@@ -1,4 +1,4 @@
1
- import {Animated} from 'react-native';
1
+ import {Animated, FlatListProps, ViewProps} from 'react-native';
2
2
  import {StackNavigationOptions} from '@react-navigation/stack';
3
3
  import React from 'react';
4
4
  import Navigator from './Navigator';
@@ -118,8 +118,8 @@ export interface ModalParams extends ScreenParams {
118
118
  export interface BottomSheetParams extends ScreenParams {
119
119
  [key: string]: any;
120
120
  onDismiss?: () => void;
121
- snapPoint?: '30%' | '50%' | '70%' | '90%' | 'content';
122
- indicatorColor?: string;
121
+ footerComponent?: React.ReactNode;
122
+ flatListProps: FlatListProps<any>;
123
123
  }
124
124
 
125
125
  export type NavigationButtonProps = {
@@ -152,6 +152,7 @@ export interface NavigationOptions extends StackNavigationOptions {
152
152
  toolkitParams?: {
153
153
  pinnedTool?: PinnedToolType;
154
154
  runtimeTools?: RuntimeToolType[];
155
+ preventClose?: PopupNotifyProps;
155
156
  };
156
157
  }
157
158
 
@@ -183,11 +184,10 @@ export type HeaderToolkitProps = {
183
184
  configs: any[];
184
185
  };
185
186
 
186
- export type HeaderAnimatedProps = {
187
+ export interface HeaderAnimatedProps extends ViewProps {
187
188
  animatedValue: Animated.Value;
188
189
  image: string;
189
- onPress?: () => void;
190
- };
190
+ }
191
191
 
192
192
  export type BottomTabItemProps = {
193
193
  name: string;
@@ -126,19 +126,14 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
126
126
  };
127
127
  }
128
128
 
129
+ if (params.toolkitParams) {
129
130
  options = {
130
131
  ...options,
131
132
  headerRight: (props: any) => {
132
- return (
133
- <HeaderToolkitAction
134
- preventBack={params.preventBack}
135
- pinnedTool={params.toolkitParams?.pinnedTool}
136
- runtimeTools={params.toolkitParams?.runtimeTools}
137
- {...props}
138
- />
139
- );
133
+ return <HeaderToolkitAction {...params.toolkitParams} {...props} />;
140
134
  },
141
135
  };
136
+ }
142
137
 
143
138
  return {
144
139
  ...params,
package/Input/styles.ts CHANGED
@@ -7,7 +7,7 @@ export default StyleSheet.create({
7
7
  input: {
8
8
  flex: 1,
9
9
  paddingLeft: Spacing.M,
10
- fontSize: scaleSize(15),
10
+ fontSize: scaleSize(14),
11
11
  },
12
12
  wrapper: {
13
13
  width: '100%',
@@ -75,7 +75,7 @@ export default StyleSheet.create({
75
75
  flex: 1,
76
76
  paddingRight: Spacing.XS,
77
77
  paddingVertical: Spacing.XS,
78
- fontSize: scaleSize(15),
78
+ fontSize: scaleSize(14),
79
79
  },
80
80
  textAreaWrapper: {
81
81
  borderWidth: 1,
@@ -108,7 +108,7 @@ export default StyleSheet.create({
108
108
  height: 36,
109
109
  marginLeft: Spacing.S,
110
110
  flex: 1,
111
- fontSize: scaleSize(15),
111
+ fontSize: scaleSize(14),
112
112
  paddingVertical: Spacing.XS,
113
113
  },
114
114
  searchInputView: {
package/Text/index.tsx CHANGED
@@ -51,8 +51,9 @@ export interface TextProps extends RNTextProps {
51
51
  */
52
52
  color?: string;
53
53
  }
54
+
54
55
  const Text: React.FC<TextProps> = ({
55
- typography,
56
+ typography = 'body_default_regular',
56
57
  color,
57
58
  children,
58
59
  style,
@@ -103,8 +104,4 @@ const Text: React.FC<TextProps> = ({
103
104
  );
104
105
  };
105
106
 
106
- Text.defaultProps = {
107
- typography: 'body_default_regular',
108
- };
109
-
110
107
  export {Text, scaleSize};
package/Text/styles.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export default {
2
- headline_default_bold: {fontSize: 24, lineHeight: 32, fontWeight: '700'},
3
- header_m_bold: {fontSize: 18, lineHeight: 28, fontWeight: '700'},
2
+ headline_default_bold: {fontSize: 24, lineHeight: 34, fontWeight: '700'},
3
+ header_m_bold: {fontSize: 18, lineHeight: 26, fontWeight: '700'},
4
4
  header_default_bold: {fontSize: 16, lineHeight: 22, fontWeight: '700'},
5
5
  header_s_semibold: {fontSize: 14, lineHeight: 20, fontWeight: '600'},
6
- header_xs_semibold: {fontSize: 12, lineHeight: 16, fontWeight: '600'},
6
+ header_xs_semibold: {fontSize: 12, lineHeight: 18, fontWeight: '600'},
7
7
  body_default_regular: {fontSize: 14, lineHeight: 20, fontWeight: '400'},
8
8
  body_regularstrikethrought: {
9
9
  fontSize: 14,
@@ -13,12 +13,12 @@ export default {
13
13
  },
14
14
  description_default_regular: {
15
15
  fontSize: 12,
16
- lineHeight: 16,
16
+ lineHeight: 18,
17
17
  fontWeight: '400',
18
18
  },
19
19
  description_default_regularstrikethrought: {
20
20
  fontSize: 12,
21
- lineHeight: 16,
21
+ lineHeight: 18,
22
22
  fontWeight: '400',
23
23
  textDecorationLine: 'line-through',
24
24
  },
@@ -30,11 +30,11 @@ export default {
30
30
  textDecorationLine: 'line-through',
31
31
  },
32
32
  label_default_medium: {fontSize: 14, lineHeight: 20, fontWeight: '500'},
33
- label_s_medium: {fontSize: 12, lineHeight: 16, fontWeight: '500'},
33
+ label_s_medium: {fontSize: 12, lineHeight: 18, fontWeight: '500'},
34
34
  label_xs_medium: {fontSize: 10, lineHeight: 14, fontWeight: '500'},
35
35
  action_default_bold: {fontSize: 16, lineHeight: 22, fontWeight: '700'},
36
36
  action_s_bold: {fontSize: 14, lineHeight: 20, fontWeight: '700'},
37
- action_xs_bold: {fontSize: 12, lineHeight: 16, fontWeight: '700'},
37
+ action_xs_bold: {fontSize: 12, lineHeight: 18, fontWeight: '700'},
38
38
  action_xxs_bold: {fontSize: 10, lineHeight: 14, fontWeight: '700'},
39
39
  /**non-support**/
40
40
  headline_default: {
package/code-scanner.js CHANGED
@@ -1,143 +1,51 @@
1
1
  const scanner = require('react-scanner');
2
- const fs = require('fs');
3
2
  const path = require('path');
4
3
 
5
- const scan = async (config) => {
6
- return await scanner.run(config);
4
+ const scan = async config => {
5
+ return await scanner.run(config);
7
6
  };
8
7
 
9
- const calcSum = (array) => {
10
- return array.reduce((a, b) => a + b, 0);
8
+ const calcSum = array => {
9
+ return array.reduce((a, b) => a + b, 0);
11
10
  };
12
11
 
13
- const calculateAdoptionRate = async (branchName , kitJsonPath , miniappJsonPath , reactNativeJsonPath , fsJsonPath ) => {
14
- const kitJson = require(kitJsonPath);
15
- const miniAppJson = require(miniappJsonPath);
16
- const reactNativeJson = require(reactNativeJsonPath);
17
- const fsJson = require(fsJsonPath);
18
-
19
- const numOfKitComponents = calcSum(Object.values(kitJson));
20
- const numOfMiniAppComponents = calcSum(Object.values(miniAppJson));
21
- const numOfReactNativeComponents = calcSum(Object.values(reactNativeJson));
22
- const numOfFSComponents = calcSum(Object.values(fsJson));
23
-
24
- const adoptionRate = ((numOfKitComponents + numOfReactNativeComponents + numOfFSComponents) / numOfMiniAppComponents) * 100;
25
-
26
- return {
27
- miniAppName: branchName,
28
- numOfKitComponents: numOfKitComponents,
29
- numOfMiniAppComponents: numOfMiniAppComponents,
30
- numOfReactNativeComponents: numOfReactNativeComponents,
31
- numOfFSComponents: numOfFSComponents,
32
- adoptionRate: adoptionRate.toFixed(2) + '%'
33
- }
12
+ const calculateAdoptionRate = (kitJsonPath, miniappJsonPath) => {
13
+ const kitJson = require(kitJsonPath);
14
+ const miniAppJson = require(miniappJsonPath);
15
+ const numOfKitComponents = calcSum(Object.values(kitJson));
16
+ const numOfMiniAppComponents = calcSum(Object.values(miniAppJson));
17
+ const adoptionRate = (numOfKitComponents / numOfMiniAppComponents) * 100;
18
+ console.log("Number of kit's components: ", numOfKitComponents);
19
+ console.log("Number of miniapp's components: ", numOfMiniAppComponents);
20
+ console.log('Adoption rate: ', adoptionRate);
34
21
  };
35
22
 
36
- function ensureFileExists(filePath , defaultContent = {}) {
37
- if (!fs.existsSync(filePath)) {
38
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
39
- fs.writeFileSync(filePath, JSON.stringify(defaultContent, null, 2));
40
- }
41
- }
42
-
43
- const sendMessage = ({
44
- numOfKitComponents,
45
- numOfMiniAppComponents,
46
- numOfFSComponents,
47
- numOfReactNativeComponents,
48
- adoptionRate,
49
- miniAppName = ''
50
- }) => {
51
- const url = 'https://chat.googleapis.com/v1/spaces/AAAAL9P6G8M/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=fnwfYuH_u0KicBnKTSSm9S0qV6azJH5v6URm8HR7V2g';
52
-
53
- const data = {
54
- text: `MiniApp: ${miniAppName}\nNumber of kit's components: ${numOfKitComponents}\nNumber of miniapp's components: ${numOfMiniAppComponents}\nNumber of FS's components: ${numOfFSComponents}\nNumber of React Native's components: ${numOfReactNativeComponents}\nAdoption rate: ${adoptionRate}`
55
- };
56
-
57
- fetch(url, {
58
- method: 'POST',
59
- headers: {
60
- 'Content-Type': 'application/json'
61
- },
62
- body: JSON.stringify(data)
63
- })
64
- .then(response => response.json())
65
- .then(data => {
66
- console.log('Success:', data);
67
- })
68
- .catch((error) => {
69
- console.error('Error:', error);
70
- });
71
- }
72
-
73
23
  const main = async () => {
74
- const rootPath = `${__dirname}/../../../`
75
- const app = path.join(`${__dirname}/../../../`, 'app.json');
76
- const appJson = require(app)
77
- const branchName = appJson.appId
78
-
79
- if (!branchName || !branchName.includes("vn.momo")){
80
- return
81
- }
82
-
83
- const scanPath = path.join(rootPath, 'src')
84
- const kitJsonPath = path.join(rootPath, './scan/kit.json')
85
- const miniappJsonPath = path.join(rootPath, './scan/miniapp.json')
86
- const reactNativeJsonPath = path.join(rootPath, './scan/RN.json')
87
- const fsJsonPath = path.join(rootPath, './scan/verLib.json')
88
-
89
- const allKitsReg = /@momo-kits/;
90
- const fsReg = /^(?:@fs-mobile-platform\/(components|investment|screens)|@miniapp-platform\/(components|foundation))$/;
91
- const RNReg = 'react-native'
92
-
93
- const config1 = {
94
- crawlFrom: scanPath,
95
- includeSubComponents: true,
96
- importedFrom: allKitsReg,
97
- processors: [['count-components', { outputTo: kitJsonPath }]],
98
- rootDir: process.cwd(),
99
- };
100
-
101
- const config2 = {
102
- crawlFrom: scanPath,
103
- includeSubComponents: true,
104
- processors: [['count-components', { outputTo: miniappJsonPath }]],
105
- rootDir: process.cwd(),
106
- };
107
-
108
- const config3 = {
109
- crawlFrom: scanPath,
110
- includeSubComponents: true,
111
- importedFrom: RNReg,
112
- processors: [['count-components', { outputTo: reactNativeJsonPath }]],
113
- rootDir: process.cwd(),
114
- };
115
-
116
- const config4 = {
117
- crawlFrom: scanPath,
118
- includeSubComponents: true,
119
- importedFrom: fsReg,
120
- processors: [['count-components', { outputTo: fsJsonPath }]],
121
- rootDir: process.cwd(),
122
- };
123
-
124
- try {
125
- ensureFileExists(kitJsonPath, {});
126
- ensureFileExists(miniappJsonPath, {});
127
- ensureFileExists(reactNativeJsonPath, {});
128
- ensureFileExists(fsJsonPath, {});
129
-
130
- await scan(config1);
131
- await scan(config2);
132
- await scan(config3);
133
- await scan(config4);
134
-
135
- const result = await calculateAdoptionRate(branchName,kitJsonPath, miniappJsonPath, reactNativeJsonPath, fsJsonPath);
136
- sendMessage(result)
137
- console.log(result)
138
- } catch (error) {
139
- console.error("Error during scan or calculation:", error);
140
- }
24
+ const [scanPath, kitJsonRelativePath, miniappJsonRelativePath] =
25
+ process.argv.slice(2);
26
+
27
+ const kitJsonPath = path.resolve(process.cwd(), kitJsonRelativePath);
28
+ const miniappJsonPath = path.resolve(process.cwd(), miniappJsonRelativePath);
29
+
30
+ const config1 = {
31
+ crawlFrom: scanPath,
32
+ includeSubComponents: true,
33
+ importedFrom: /@momo-kits\/.+/,
34
+ processors: [['count-components', {outputTo: kitJsonPath}]],
35
+ rootDir: './',
36
+ };
37
+
38
+ const config2 = {
39
+ crawlFrom: scanPath,
40
+ includeSubComponents: true,
41
+ processors: [['count-components', {outputTo: miniappJsonPath}]],
42
+ rootDir: './',
43
+ };
44
+
45
+ await scan(config1);
46
+ await scan(config2);
47
+
48
+ calculateAdoptionRate(kitJsonPath, miniappJsonPath);
141
49
  };
142
50
 
143
- main();
51
+ main().catch(console.error);
package/package.json CHANGED
@@ -1,27 +1,26 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.89.5-beta.18",
3
+ "version": "0.89.6",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {
7
- "postinstall": "node code-scanner.js"
7
+ "postinstall": "node verify.js"
8
8
  },
9
9
  "keywords": [
10
10
  "@momo-kits/foundation"
11
11
  ],
12
12
  "dependencies": {
13
- "@gorhom/bottom-sheet": "git+https://gitlab.com/momo-platform/bottom-sheet.git#main",
14
13
  "react-native-safe-area-context": "3.1.4",
15
14
  "react-native-linear-gradient": "2.8.3",
16
15
  "react-native-gesture-handler": "1.10.3",
16
+ "react-native-modalize": "2.1.1",
17
17
  "react-native-fast-image": "8.1.5",
18
18
  "@react-navigation/bottom-tabs": "git+https://gitlab.com/momo-platform/react-navigation-bottom-tabs.git#main",
19
19
  "@react-navigation/core": "5.16.1",
20
20
  "@react-navigation/native": "5.9.8",
21
21
  "@react-navigation/routers": "5.7.4",
22
22
  "lottie-react-native": "3.3.2",
23
- "@react-navigation/stack": "git+https://gitlab.com/momo-platform/react-navigation-stack.git#main",
24
- "react-scanner": "^1.1.0"
23
+ "@react-navigation/stack": "git+https://gitlab.com/momo-platform/react-navigation-stack.git#main"
25
24
  },
26
25
  "peerDependencies": {
27
26
  "react-native": "*"
package/verify.js CHANGED
@@ -2,25 +2,24 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
4
  try {
5
- const package = path.join(`${__dirname}`, 'package.json');
6
- const packageInfo = JSON.parse(fs.readFileSync(package, 'utf8'));
5
+ const packageInfo = JSON.parse(
6
+ fs.readFileSync(path.join(`${__dirname}`, 'package.json'), 'utf8'),
7
+ );
7
8
  const packageVersion = parseInt(packageInfo?.version.split('.')?.[1]);
8
9
 
9
10
  const app = path.join(`${__dirname}/../../../`, 'app.json');
10
11
  const miniJson = path.join(`${__dirname}/../../../`, 'package.json');
12
+
13
+ if (!fs.existsSync(app) || fs.existsSync(miniJson)) {
14
+ return;
15
+ }
16
+
11
17
  const appInfo = JSON.parse(fs.readFileSync(app, 'utf8'));
12
18
  const miniInfo = JSON.parse(fs.readFileSync(miniJson, 'utf8'));
19
+
13
20
  const iOSAppTarget = appInfo?.client?.ios.deploymentTarget;
14
21
  const androidAppTarget = appInfo?.client?.android.deploymentTarget;
15
22
 
16
- if (Object.values(appInfo).length < 1) {
17
- return
18
- }
19
-
20
- if (appInfo.name === 'MoMoPlatform') {
21
- return;
22
- }
23
-
24
23
  if (packageVersion > iOSAppTarget || packageVersion > androidAppTarget) {
25
24
  console.error(
26
25
  `Package ${packageInfo.name} version: ${packageInfo.version} require deploymentTarget ${packageVersion}`,