@momo-kits/foundation 0.89.2 → 0.89.3-tracking.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.
@@ -104,7 +104,6 @@ const BottomTab: React.FC<BottomTabProps> = ({
104
104
  left: item?.showDot ? 8 : 4,
105
105
  top: item?.showDot ? -2 : -6,
106
106
  },
107
-
108
107
  tabBarIcon: ({color}) => (
109
108
  <Icon source={item.icon} color={color} size={28} />
110
109
  ),
@@ -1,4 +1,4 @@
1
- import React, {useEffect, useRef, useState} from 'react';
1
+ import React, {useContext, useEffect, useRef, useState} from 'react';
2
2
  import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
3
3
  import {SafeAreaProvider} from 'react-native-safe-area-context';
4
4
  import {
@@ -6,13 +6,13 @@ import {
6
6
  NavigationContainerRef,
7
7
  } from '@react-navigation/native';
8
8
  import {createStackNavigator} from '@react-navigation/stack';
9
- import {DeviceEventEmitter, NativeModules} from 'react-native';
9
+ import {DeviceEventEmitter} from 'react-native';
10
10
  import StackScreen from './StackScreen';
11
11
  import ModalScreen from './ModalScreen';
12
12
  import Navigator from './Navigator';
13
13
  import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
14
14
  import {LocalizationObject, NavigationContainerProps} from './types';
15
- import {ApplicationContext} from './index';
15
+ import {ApplicationContext, MiniAppContext} from './index';
16
16
  import kitLocalization from '../Assets/language.json';
17
17
 
18
18
  const Stack = createStackNavigator();
@@ -24,41 +24,25 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
24
24
  maxApi,
25
25
  localization,
26
26
  }) => {
27
+ const context = useContext(MiniAppContext);
27
28
  const navigationRef = React.useRef<NavigationContainerRef>(null);
28
29
  const navigator = useRef(new Navigator(navigationRef));
29
30
  const [showGrid, setShowGrid] = useState(false);
30
- const [language, setLanguage] = useState<'vi' | 'en'>('vi');
31
- const [config, setConfig] = useState<any>(undefined);
32
- let assets = theme.assets;
33
- if (config && theme.assets?.headerBackground) {
34
- assets = {...assets, headerBackground: config.navigationBar?.headerBar};
35
- }
31
+ const config = useRef<any>();
36
32
 
37
33
  /**
38
34
  * handle mini language & listen change
39
35
  * engine only shake to enable grid view
40
36
  */
41
37
  useEffect(() => {
42
- maxApi?.getLanguage?.((lang: 'vi' | 'en') => {
43
- setLanguage(lang);
44
- });
45
- const listener = maxApi?.observer?.('language', (lang: 'vi' | 'en') => {
46
- setLanguage(lang);
47
- });
48
38
  const subscription = DeviceEventEmitter.addListener(
49
39
  'onChangeGrid',
50
40
  enable => {
51
41
  setShowGrid(!!enable);
52
42
  },
53
43
  );
54
- try {
55
- const result = JSON.parse(
56
- NativeModules?.ConfigsModule?.getConfigSync?.('DESIGN_SYSTEM'),
57
- );
58
- setConfig(result);
59
- } catch (e) {}
44
+
60
45
  return () => {
61
- listener?.remove?.();
62
46
  subscription?.remove?.();
63
47
  };
64
48
  }, []);
@@ -73,6 +57,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
73
57
  * @param key
74
58
  */
75
59
  const translate = (key: string) => {
60
+ const language: 'vi' | 'en' = context?.language ?? 'vi';
76
61
  const mergedLocalization: LocalizationObject = {
77
62
  vi: {...localization?.vi, ...kitLocalization.vi},
78
63
  en: {...localization?.en, ...kitLocalization.en},
@@ -85,14 +70,10 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
85
70
  <BottomSheetModalProvider>
86
71
  <ApplicationContext.Provider
87
72
  value={{
88
- theme: {
89
- ...theme,
90
- assets: assets,
91
- },
92
73
  navigator: navigator.current,
74
+ config: config.current,
75
+ theme,
93
76
  showGrid,
94
- language,
95
- config,
96
77
  translate,
97
78
  }}>
98
79
  <ReactNavigationContainer
@@ -109,6 +109,18 @@ class Navigator {
109
109
  );
110
110
  };
111
111
 
112
+ /**
113
+ * dismiss a feature data
114
+ * @param data
115
+ */
116
+ setDismissData = (data: any) => {
117
+ this.dismissData = data;
118
+ };
119
+
120
+ /**
121
+ * set callback function for toolkit
122
+ * @param callback
123
+ */
112
124
  setToolkitCallback = (
113
125
  callback: (item: {key: string; action: string}) => void,
114
126
  ) => {
@@ -5,6 +5,10 @@ import {ApplicationContext, MiniAppContext} from './index';
5
5
  import {GridSystem} from '../Layout';
6
6
  import {useHeaderHeight} from '@react-navigation/stack';
7
7
 
8
+ const {
9
+ ScreenContext,
10
+ } = require('react-native/Libraries/Components/ScreenContext');
11
+
8
12
  const StackScreen: React.FC<ScreenParams> = props => {
9
13
  const {theme, showGrid, navigator} = useContext(ApplicationContext);
10
14
  const context = useContext(MiniAppContext);
@@ -61,10 +65,17 @@ const StackScreen: React.FC<ScreenParams> = props => {
61
65
  }, []);
62
66
 
63
67
  return (
64
- <>
68
+ <ScreenContext.Provider
69
+ value={{
70
+ ...context,
71
+ screenName: Component.name,
72
+ autoTracking: (data: any) => {
73
+ navigator?.maxApi?.dispatchFunction?.('autoTracking', data);
74
+ },
75
+ }}>
65
76
  <Component heightHeader={heightHeader} {...params} />
66
77
  {showGrid && <GridSystem />}
67
- </>
78
+ </ScreenContext.Provider>
68
79
  );
69
80
  };
70
81
 
@@ -67,7 +67,6 @@ export type Context = {
67
67
  theme: Theme;
68
68
  navigator?: Navigator;
69
69
  showGrid?: boolean;
70
- language?: 'vi' | 'en';
71
70
  translate?: (key: string) => string;
72
71
  };
73
72
 
package/Button/index.tsx CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  TouchableOpacityProps,
7
7
  View,
8
8
  } from 'react-native';
9
-
10
9
  import LinearGradient from 'react-native-linear-gradient';
11
10
  import {ApplicationContext} from '../Application';
12
11
  import {Text} from '../Text';
@@ -16,6 +15,10 @@ import styles from './styles';
16
15
  import {Icon} from '../Icon';
17
16
  import {Loader} from '../Loader';
18
17
 
18
+ const {
19
+ ScreenContext,
20
+ } = require('react-native/Libraries/Components/ScreenContext');
21
+
19
22
  const AnimationLinear = Animated.createAnimatedComponent(LinearGradient);
20
23
 
21
24
  export interface ButtonProps extends TouchableOpacityProps {
@@ -70,6 +73,10 @@ export interface ButtonProps extends TouchableOpacityProps {
70
73
  * A callback function that is called when the button is pressed.
71
74
  */
72
75
  onPress: () => void;
76
+
77
+ params?: any;
78
+
79
+ componentId?: string;
73
80
  }
74
81
 
75
82
  const Button: FC<ButtonProps> = ({
@@ -82,6 +89,8 @@ const Button: FC<ButtonProps> = ({
82
89
  loading = false,
83
90
  title = 'Button',
84
91
  onPress,
92
+ params,
93
+ componentId,
85
94
  ...rest
86
95
  }) => {
87
96
  const {theme, config} = useContext(ApplicationContext);
@@ -94,6 +103,8 @@ const Button: FC<ButtonProps> = ({
94
103
  end: {x: 0, y: 0.5},
95
104
  };
96
105
  }
106
+
107
+ const screenInfo = useContext<any>(ScreenContext);
97
108
  const getSizeStyle = () => {
98
109
  const styleSheet: {[key: string]: any} = styles;
99
110
  return styleSheet[size ?? 'small'];
@@ -291,20 +302,29 @@ const Button: FC<ButtonProps> = ({
291
302
  const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
292
303
 
293
304
  return (
294
- <TouchableOpacity
295
- {...rest}
296
- accessibilityLabel={`Button/${title}`}
297
- activeOpacity={activeOpacity}
298
- onPress={onPressButton}
299
- style={buttonStyle}>
300
- {renderLeading()}
301
- {renderTitle()}
302
- {renderTrailing()}
303
- {gradientPros && (
304
- <AnimationLinear {...gradientPros} style={styles.gradientView} />
305
- )}
306
- {gradientPros && <View style={styles.strokeView} />}
307
- </TouchableOpacity>
305
+ <ScreenContext.Provider
306
+ value={{
307
+ ...screenInfo,
308
+ componentName: 'Button',
309
+ params,
310
+ state: type === 'disabled' ? 'disabled' : 'enabled',
311
+ componentId,
312
+ action: 'click',
313
+ }}>
314
+ <TouchableOpacity
315
+ {...rest}
316
+ activeOpacity={activeOpacity}
317
+ onPress={onPressButton}
318
+ style={buttonStyle}>
319
+ {renderLeading()}
320
+ {renderTitle()}
321
+ {renderTrailing()}
322
+ {gradientPros && (
323
+ <AnimationLinear {...gradientPros} style={styles.gradientView} />
324
+ )}
325
+ {gradientPros && <View style={styles.strokeView} />}
326
+ </TouchableOpacity>
327
+ </ScreenContext.Provider>
308
328
  );
309
329
  };
310
330
 
@@ -10,6 +10,10 @@ import {Colors} from '../Consts';
10
10
  import {Icon} from '../Icon';
11
11
  import styles from './styles';
12
12
 
13
+ const {
14
+ ScreenContext,
15
+ } = require('react-native/Libraries/Components/ScreenContext');
16
+
13
17
  export interface IconButtonProps extends TouchableOpacityProps {
14
18
  /**
15
19
  * Represents the name or key of the icon to be displayed on the IconButton.
@@ -26,6 +30,10 @@ export interface IconButtonProps extends TouchableOpacityProps {
26
30
  * Optional. Defines the size of the IconButton.
27
31
  */
28
32
  size?: 'large' | 'small';
33
+
34
+ params?: any;
35
+
36
+ componentId?: string;
29
37
  }
30
38
 
31
39
  const IconButton: React.FC<IconButtonProps> = ({
@@ -33,9 +41,12 @@ const IconButton: React.FC<IconButtonProps> = ({
33
41
  icon,
34
42
  size,
35
43
  onPress,
44
+ params,
45
+ componentId,
36
46
  ...rest
37
47
  }) => {
38
48
  const {theme} = useContext(ApplicationContext);
49
+ const screenInfo = useContext<any>(ScreenContext);
39
50
 
40
51
  /**
41
52
  * get size icon button
@@ -121,14 +132,23 @@ const IconButton: React.FC<IconButtonProps> = ({
121
132
  const iconSize = size === 'small' ? 16 : 24;
122
133
 
123
134
  return (
124
- <TouchableOpacity
125
- {...rest}
126
- accessibilityLabel={`IconButton/${icon}`}
127
- activeOpacity={activeOpacity}
128
- onPress={onPressButton}
129
- style={buttonStyle}>
130
- <Icon size={iconSize} source={icon} color={getIconColor()} />
131
- </TouchableOpacity>
135
+ <ScreenContext.Provider
136
+ value={{
137
+ ...screenInfo,
138
+ componentName: 'IconButton',
139
+ params,
140
+ state: type === 'disabled' ? 'disabled' : 'enabled',
141
+ componentId,
142
+ action: 'click',
143
+ }}>
144
+ <TouchableOpacity
145
+ {...rest}
146
+ activeOpacity={activeOpacity}
147
+ onPress={onPressButton}
148
+ style={buttonStyle}>
149
+ <Icon size={iconSize} source={icon} color={getIconColor()} />
150
+ </TouchableOpacity>
151
+ </ScreenContext.Provider>
132
152
  );
133
153
  };
134
154
 
package/Input/Input.tsx CHANGED
@@ -14,6 +14,10 @@ import {Icon} from '../Icon';
14
14
  import {checkTyping} from './utils';
15
15
  import {Loader} from '../Loader';
16
16
 
17
+ const {
18
+ ScreenContext,
19
+ } = require('react-native/Libraries/Components/ScreenContext');
20
+
17
21
  const Input = forwardRef(
18
22
  (
19
23
  {
@@ -38,6 +42,8 @@ const Input = forwardRef(
38
42
  fontWeight = 'Regular',
39
43
  onPressIcon,
40
44
  style,
45
+ params,
46
+ componentId,
41
47
  ...props
42
48
  }: InputProps,
43
49
  ref,
@@ -47,6 +53,7 @@ const Input = forwardRef(
47
53
  const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
48
54
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
49
55
  const accessibilityLabel = `Input/${floatingValue ?? placeholder}`;
56
+ const screenInfo = useContext<any>(ScreenContext);
50
57
 
51
58
  const onClearText = () => {
52
59
  inputRef?.current?.clear();
@@ -160,12 +167,21 @@ const Input = forwardRef(
160
167
  };
161
168
 
162
169
  return (
163
- <View
164
- style={[style, styles.wrapper]}
165
- accessibilityLabel={accessibilityLabel}>
166
- {renderInputView()}
167
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
168
- </View>
170
+ <ScreenContext.Provider
171
+ value={{
172
+ ...screenInfo,
173
+ componentName: 'Input',
174
+ params,
175
+ state: disabled ? 'disabled' : 'enabled',
176
+ componentId,
177
+ }}>
178
+ <View
179
+ style={[style, styles.wrapper]}
180
+ accessibilityLabel={accessibilityLabel}>
181
+ {renderInputView()}
182
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
183
+ </View>
184
+ </ScreenContext.Provider>
169
185
  );
170
186
  },
171
187
  );
@@ -19,6 +19,10 @@ import {InputMoneyProps} from './index';
19
19
  import {Icon} from '../Icon';
20
20
  import {formatMoneyToNumber, formatNumberToMoney} from './utils';
21
21
 
22
+ const {
23
+ ScreenContext,
24
+ } = require('react-native/Libraries/Components/ScreenContext');
25
+
22
26
  const InputMoney = forwardRef(
23
27
  (
24
28
  {
@@ -36,7 +40,9 @@ const InputMoney = forwardRef(
36
40
  required = false,
37
41
  errorSpacing,
38
42
  style,
43
+ params,
39
44
  defaultValue = '',
45
+ componentId,
40
46
  ...props
41
47
  }: InputMoneyProps,
42
48
  ref,
@@ -45,6 +51,7 @@ const InputMoney = forwardRef(
45
51
  const [focused, setFocused] = useState(false);
46
52
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
47
53
  const accessibilityLabel = `InputMoney/${floatingValue}`;
54
+ const screenInfo = useContext<any>(ScreenContext);
48
55
 
49
56
  const validateText = (text: string) => {
50
57
  const valueFormat = formatMoneyToNumber(text, 'đ');
@@ -154,12 +161,21 @@ const InputMoney = forwardRef(
154
161
  };
155
162
 
156
163
  return (
157
- <View
158
- style={[style, styles.wrapper]}
159
- accessibilityLabel={accessibilityLabel}>
160
- {renderInputView()}
161
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
162
- </View>
164
+ <ScreenContext.Provider
165
+ value={{
166
+ ...screenInfo,
167
+ componentName: 'InputMoney',
168
+ params,
169
+ state: disabled ? 'disabled' : 'enabled',
170
+ componentId,
171
+ }}>
172
+ <View
173
+ style={[style, styles.wrapper]}
174
+ accessibilityLabel={accessibilityLabel}>
175
+ {renderInputView()}
176
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
177
+ </View>
178
+ </ScreenContext.Provider>
163
179
  );
164
180
  },
165
181
  );
@@ -22,6 +22,10 @@ import {ErrorView, getBorderColor} from './common';
22
22
  import {ApplicationContext} from '../Application';
23
23
  import {Spacing} from '../Consts';
24
24
 
25
+ const {
26
+ ScreenContext,
27
+ } = require('react-native/Libraries/Components/ScreenContext');
28
+
25
29
  const OTPCaret: FC<CaretProps> = ({index, length}) => {
26
30
  const DURATION = 300;
27
31
  const {theme} = useContext(ApplicationContext);
@@ -78,7 +82,9 @@ const InputOTP = forwardRef(
78
82
  onFocus,
79
83
  onBlur,
80
84
  dataType = 'number',
85
+ params,
81
86
  style,
87
+ componentId,
82
88
  ...props
83
89
  }: InputOTPProps,
84
90
  ref,
@@ -89,6 +95,7 @@ const InputOTP = forwardRef(
89
95
  const inputRef = useRef<TextInput>(null);
90
96
  const {theme} = useContext(ApplicationContext);
91
97
  const accessibilityLabel = `InputOTP/${floatingValue ?? placeholder}`;
98
+ const screenInfo = useContext<any>(ScreenContext);
92
99
 
93
100
  useImperativeHandle(ref, () => ({
94
101
  onChangeText: (text: string) => {
@@ -223,14 +230,23 @@ const InputOTP = forwardRef(
223
230
  };
224
231
 
225
232
  return (
226
- <TouchableOpacity
227
- activeOpacity={1}
228
- onPress={onFocusInput}
229
- style={[style, styles.otpWrapper]}
230
- accessibilityLabel={accessibilityLabel}>
231
- {renderInputView()}
232
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
233
- </TouchableOpacity>
233
+ <ScreenContext.Provider
234
+ value={{
235
+ ...screenInfo,
236
+ componentName: 'InputOTP',
237
+ params,
238
+ state: 'enabled',
239
+ componentId,
240
+ }}>
241
+ <TouchableOpacity
242
+ activeOpacity={1}
243
+ onPress={onFocusInput}
244
+ style={[style, styles.otpWrapper]}
245
+ accessibilityLabel={accessibilityLabel}>
246
+ {renderInputView()}
247
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
248
+ </TouchableOpacity>
249
+ </ScreenContext.Provider>
234
250
  );
235
251
  },
236
252
  );
@@ -13,6 +13,10 @@ import {Icon} from '../Icon';
13
13
  import {Text} from '../Text';
14
14
  import {checkTyping} from './utils';
15
15
 
16
+ const {
17
+ ScreenContext,
18
+ } = require('react-native/Libraries/Components/ScreenContext');
19
+
16
20
  const InputSearch = forwardRef(
17
21
  (
18
22
  {
@@ -29,6 +33,8 @@ const InputSearch = forwardRef(
29
33
  style,
30
34
  defaultValue,
31
35
  onPressButtonText,
36
+ params,
37
+ componentId,
32
38
  ...props
33
39
  }: InputSearchProps,
34
40
  ref,
@@ -38,6 +44,7 @@ const InputSearch = forwardRef(
38
44
  const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
39
45
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
40
46
  const accessibilityLabel = `InputMoney/${placeholder}`;
47
+ const screenInfo = useContext<any>(ScreenContext);
41
48
 
42
49
  const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
43
50
  setFocused(true);
@@ -119,35 +126,46 @@ const InputSearch = forwardRef(
119
126
  );
120
127
  };
121
128
  return (
122
- <View
123
- style={[style, styles.searchInputContainer]}
124
- accessibilityLabel={accessibilityLabel}>
129
+ <ScreenContext.Provider
130
+ value={{
131
+ ...screenInfo,
132
+ componentName: 'InputSearch',
133
+ params,
134
+ state: 'enabled',
135
+ componentId,
136
+ }}>
125
137
  <View
126
- style={[
127
- styles.searchInputWrapper,
128
- {
129
- backgroundColor: theme.colors.background.surface,
130
- borderColor: theme.colors.background.surface,
131
- },
132
- showBorder && {borderColor: theme.colors.border.default},
133
- focused && {borderColor: theme.colors.primary},
134
- ]}>
135
- <Icon
136
- source={'navigation_search'}
137
- size={24}
138
- color={theme.colors.text.hint}
139
- />
140
- {renderInputView()}
141
- {renderIconView()}
138
+ style={[style, styles.searchInputContainer]}
139
+ accessibilityLabel={accessibilityLabel}>
140
+ <View
141
+ style={[
142
+ styles.searchInputWrapper,
143
+ {
144
+ backgroundColor: theme.colors.background.surface,
145
+ borderColor: theme.colors.background.surface,
146
+ },
147
+ showBorder && {borderColor: theme.colors.border.default},
148
+ focused && {borderColor: theme.colors.primary},
149
+ ]}>
150
+ <Icon
151
+ source={'navigation_search'}
152
+ size={24}
153
+ color={theme.colors.text.hint}
154
+ />
155
+ {renderInputView()}
156
+ {renderIconView()}
157
+ </View>
158
+ {showButtonText && (
159
+ <TouchableOpacity onPress={onPressButtonText}>
160
+ <Text
161
+ typography={'action_default_bold'}
162
+ style={styles.textButton}>
163
+ {buttonText}
164
+ </Text>
165
+ </TouchableOpacity>
166
+ )}
142
167
  </View>
143
- {showButtonText && (
144
- <TouchableOpacity onPress={onPressButtonText}>
145
- <Text typography={'action_default_bold'} style={styles.textButton}>
146
- {buttonText}
147
- </Text>
148
- </TouchableOpacity>
149
- )}
150
- </View>
168
+ </ScreenContext.Provider>
151
169
  );
152
170
  },
153
171
  );
package/Input/index.tsx CHANGED
@@ -80,6 +80,9 @@ export interface InputProps extends TextInputProps {
80
80
  fontWeight?: 'Regular' | 'Bold';
81
81
 
82
82
  onPressIcon?: () => void;
83
+
84
+ params?: any;
85
+ componentId?: string;
83
86
  }
84
87
 
85
88
  type InputPropsWithoutSizeAndIcon = Omit<
@@ -126,6 +129,10 @@ export interface InputSearchProps extends TextInputProps {
126
129
  * Optional. Represents the name or key of the icon to be displayed in the Input component.
127
130
  */
128
131
  icon?: string;
132
+
133
+ params?: any;
134
+
135
+ componentId?: string;
129
136
  }
130
137
 
131
138
  export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.89.2",
3
+ "version": "0.89.3-tracking.1",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {