@momo-kits/foundation 0.92.3-tracking.2 → 0.92.3-tracking.21

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.
@@ -28,12 +28,12 @@ import {Radius} from '../../Consts';
28
28
  import {Icon} from '../../Icon';
29
29
  import {Text} from '../../Text';
30
30
  import {FloatingButtonProps} from '../types';
31
- import {getAccessibilityID} from '../utils';
32
31
 
33
32
  type Props = BottomTabBarProps & {
34
33
  activeTintColor?: string;
35
34
  inactiveTintColor?: string;
36
35
  floatingButton?: FloatingButtonProps;
36
+ accessibilityLabel?: string;
37
37
  };
38
38
 
39
39
  type Options = {
@@ -317,7 +317,6 @@ export default function BottomTabBar({
317
317
  labelStyle={labelStyle}
318
318
  iconStyle={iconStyle}
319
319
  style={tabStyle}
320
- {...getAccessibilityID(`btn_tabbar_${route.name}`)}
321
320
  />
322
321
  </NavigationRouteContext.Provider>
323
322
  </NavigationContext.Provider>
@@ -9,7 +9,7 @@ import {Text} from '../../Text';
9
9
  import {ApplicationContext} from '../index';
10
10
  import StackScreen from '../StackScreen';
11
11
  import {BottomTabProps, NavigationScreenProps} from '../types';
12
- import {getAccessibilityID, getStackOptions} from '../utils';
12
+ import {getStackOptions} from '../utils';
13
13
  import BottomTabBar from './BottomTabBar';
14
14
 
15
15
  const Tab = createBottomTabNavigator();
@@ -67,8 +67,8 @@ const BottomTab: React.FC<BottomTabProps> = ({
67
67
  backBehavior={'firstRoute'}
68
68
  tabBar={props => (
69
69
  <BottomTabBar
70
- {...getAccessibilityID('tbr_main_bottom')}
71
70
  {...props}
71
+ accessibilityLabel={'BottomTabBar'}
72
72
  floatingButton={floatingButton}
73
73
  />
74
74
  )}
@@ -29,7 +29,6 @@ import {scaleSize, Text} from '../Text';
29
29
  import {Icon} from '../Icon';
30
30
  import {PopupNotify} from '../Popup';
31
31
  import {Badge, BadgeDot} from '../Badge';
32
- import {getAccessibilityID} from './utils';
33
32
 
34
33
  const NavigationButton: React.FC<NavigationButtonProps> = ({
35
34
  icon,
@@ -38,7 +37,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
38
37
  useBorder = true,
39
38
  badgeType,
40
39
  badgeValue,
41
- accessibilityID = '',
40
+ accessibilityLabel = '',
42
41
  }) => {
43
42
  const {theme} = useContext(ApplicationContext);
44
43
  let buttonStyle: ViewStyle = {backgroundColor: '#00000066'};
@@ -66,10 +65,9 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
66
65
  }, [badgeType, badgeValue]);
67
66
 
68
67
  return (
69
- <View
70
- {...getAccessibilityID(accessibilityID)}
71
- style={{width: scaleSize(28)}}>
68
+ <View style={{width: scaleSize(28)}}>
72
69
  <TouchableOpacity
70
+ accessibilityLabel={accessibilityLabel}
73
71
  style={[styles.navigationButton, buttonStyle]}
74
72
  onPress={onPress}>
75
73
  <Icon
@@ -94,7 +92,7 @@ const HeaderTitle: React.FC<any> = props => {
94
92
  return (
95
93
  <Animated.Text
96
94
  {...props}
97
- {...getAccessibilityID('title_navigation_header')}
95
+ accessibilityLabel={'title_navigation_header'}
98
96
  style={[
99
97
  styles.title,
100
98
  {fontFamily: `${theme.font}-Bold`, opacity, color: props.tintColor},
@@ -173,7 +171,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
173
171
  return (
174
172
  <View style={styles.headerLeft}>
175
173
  <NavigationButton
176
- accessibilityID="btn_navigation_back"
174
+ accessibilityLabel="btn_navigation_back"
177
175
  icon="ic_back"
178
176
  tintColor={tintColor}
179
177
  onPress={goBackSafe}
@@ -248,7 +246,7 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
248
246
  </View>
249
247
  <View style={[Styles.flex, {paddingHorizontal: 8}]}>
250
248
  <Text
251
- {...getAccessibilityID('title_navigation_header')}
249
+ accessibilityLabel={'title_navigation_header'}
252
250
  typography="header_default_bold"
253
251
  color={tintColor}>
254
252
  {title}
@@ -376,7 +374,7 @@ const HeaderToolkitAction: React.FC<any> = ({
376
374
  if (pinTool)
377
375
  return (
378
376
  <NavigationButton
379
- accessibilityID="btn_navigation_pin"
377
+ accessibilityLabel="btn_navigation_pin"
380
378
  icon={pinTool.icon as string}
381
379
  tintColor={tintColor}
382
380
  badgeValue={badgeValue}
@@ -407,13 +405,13 @@ const HeaderToolkitAction: React.FC<any> = ({
407
405
  },
408
406
  ]}>
409
407
  <TouchableOpacity
410
- {...getAccessibilityID('btn_navigation_more')}
408
+ accessibilityLabel={'btn_navigation_more'}
411
409
  onPress={onMore}>
412
410
  <Icon color={tintColor} source="navigation_more_horiz" size={20} />
413
411
  </TouchableOpacity>
414
412
  <View style={[styles.divider, {backgroundColor: tintColor}]} />
415
413
  <TouchableOpacity
416
- {...getAccessibilityID('btn_navigation_close')}
414
+ accessibilityLabel={'btn_navigation_close'}
417
415
  onPress={onClose}>
418
416
  <Icon
419
417
  color={tintColor}
@@ -117,9 +117,6 @@ const StackScreen: React.FC<ScreenParams> = props => {
117
117
  <ScreenContext.Provider
118
118
  value={{
119
119
  screenName,
120
- autoTracking: (data: any) => {
121
- navigator?.maxApi?.dispatchFunction?.('autoTracking', data);
122
- },
123
120
  onElementLoad: () => {
124
121
  endTime.current = Date.now();
125
122
  interaction.current?.cancel?.();
@@ -130,7 +130,7 @@ export type NavigationButtonProps = {
130
130
  onPress: () => void;
131
131
  badgeType?: 'dot' | 'number';
132
132
  badgeValue?: number;
133
- accessibilityID?: string;
133
+ accessibilityLabel?: string;
134
134
  };
135
135
 
136
136
  export type PinnedToolType = {
@@ -158,41 +158,6 @@ const getAccessibilityID = (
158
158
  }
159
159
  };
160
160
 
161
- const cleanNameForTracking = (word = ''): string => {
162
- return word
163
- .normalize('NFD')
164
- .replace(/[\u0300-\u036f |\s]/g, '')
165
- .toLowerCase();
166
- };
167
-
168
- const formatComponentName = (word = '') => {
169
- const accentsMap = {
170
- a: 'á|à|ả|ã|ạ|â|ấ|ầ|ẩ|ẫ|ậ|ă|ắ|ằ|ẳ|ẵ|ặ',
171
- A: 'Á|À|Ả|Ã|Ạ|Â|Ấ|Ầ|Ẩ|Ẫ|Ậ|Ă|Ắ|Ằ|Ẳ|Ẵ|Ặ',
172
- e: 'é|è|ẻ|ẽ|ẹ|ê|ế|ề|ể|ễ|ệ',
173
- E: 'É|È|Ẻ|Ẽ|Ẹ|Ê|Ế|Ề|Ể|Ễ|Ệ',
174
- i: 'í|ì|ỉ|ĩ|ị',
175
- I: 'Í|Ì|Ỉ|Ĩ|Ị',
176
- o: 'ó|ò|ỏ|õ|ọ|ô|ố|ồ|ổ|ỗ|ộ|ơ|ớ|ờ|ở|ỡ|ợ',
177
- O: 'Ó|Ò|Ỏ|Õ|Ọ|Ô|Ố|Ồ|Ổ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ở|Ỡ|Ợ',
178
- u: 'ú|ù|ủ|ũ|ụ|ư|ứ|ừ|ử|ữ|ự',
179
- U: 'Ú|Ù|Ủ|Ũ|Ụ|Ư|Ứ|Ừ|Ử|Ữ|Ự',
180
- y: 'ý|ỳ|ỷ|ỹ|ỵ',
181
- Y: 'Ý|Ỳ|Ỷ|Ỹ|Ỵ',
182
- d: 'đ',
183
- D: 'Đ',
184
- };
185
-
186
- for (const [nonAccent, accentGroup] of Object.entries(accentsMap)) {
187
- const accents = new RegExp(accentGroup, 'g');
188
- word = word.replace(accents, nonAccent);
189
- }
190
-
191
- word = word.replace(/\s+/g, '_').toLowerCase();
192
-
193
- return word;
194
- };
195
-
196
161
  const formatNameLength = (name = '') => {
197
162
  let formattedName = name;
198
163
  if (formattedName.length > 100) {
@@ -205,8 +170,6 @@ export {
205
170
  getDialogOptions,
206
171
  getModalOptions,
207
172
  getOptions,
208
- formatComponentName,
209
173
  formatNameLength,
210
174
  getAccessibilityID,
211
- cleanNameForTracking,
212
175
  };
package/Button/index.tsx CHANGED
@@ -14,7 +14,6 @@ import {Colors, Spacing} from '../Consts';
14
14
  import styles from './styles';
15
15
  import {Icon} from '../Icon';
16
16
  import {Loader} from '../Loader';
17
- import {formatComponentName} from '../Application/utils';
18
17
 
19
18
  const AnimationLinear = Animated.createAnimatedComponent(LinearGradient);
20
19
 
@@ -306,7 +305,7 @@ const Button: FC<ButtonProps> = ({
306
305
  params,
307
306
  state: state,
308
307
  componentId: accessibilityLabel,
309
- componentValue: formatComponentName(title),
308
+ componentValue: title,
310
309
  action: 'click',
311
310
  }}>
312
311
  <TouchableOpacity
@@ -46,7 +46,7 @@ const CheckBox: FC<CheckBoxProps> = ({
46
46
  componentId: accessibilityLabel,
47
47
  action: 'click',
48
48
  componentLabel: formatNameLength(label || ''),
49
- componentValue: indeterminate ? 'indetermine' : value,
49
+ componentValue: indeterminate ? 'undetermined' : value,
50
50
  }}>
51
51
  <TouchableOpacity
52
52
  accessibilityLabel={accessibilityLabel}
@@ -9,7 +9,6 @@ import {ApplicationContext, ComponentContext} from '../Application';
9
9
  import {Colors} from '../Consts';
10
10
  import {Icon} from '../Icon';
11
11
  import styles from './styles';
12
- import {formatComponentName} from '../Application/utils';
13
12
 
14
13
  export interface IconButtonProps extends TouchableOpacityProps {
15
14
  /**
@@ -132,7 +131,7 @@ const IconButton: React.FC<IconButtonProps> = ({
132
131
  params,
133
132
  state: type === 'disabled' ? 'disabled' : 'enabled',
134
133
  componentId: accessibilityLabel,
135
- componentValue: formatComponentName(icon),
134
+ componentValue: icon,
136
135
  action: 'click',
137
136
  }}>
138
137
  <TouchableOpacity
package/Image/index.tsx CHANGED
@@ -7,7 +7,6 @@ import {Skeleton} from '../Skeleton';
7
7
  import {Icon} from '../Icon';
8
8
  import {Styles} from '../Consts';
9
9
  import {ImageProps} from './types';
10
- import {getAccessibilityID} from '../Application/utils';
11
10
 
12
11
  type Status = 'success' | 'loading' | 'error';
13
12
 
@@ -16,6 +15,7 @@ const Image: React.FC<ImageProps> = ({
16
15
  source,
17
16
  loading = true,
18
17
  children,
18
+ params,
19
19
  accessibilityLabel,
20
20
  ...rest
21
21
  }) => {
@@ -24,13 +24,13 @@ const Image: React.FC<ImageProps> = ({
24
24
  const error = useRef(false);
25
25
  const [status, setStatus] = useState<Status>('success');
26
26
 
27
- const id = getAccessibilityID(
28
- `img|${(source as Source).uri}`,
29
- accessibilityLabel,
30
- );
27
+ const test: any = {
28
+ accessibilityLabel: accessibilityLabel || `img|${(source as Source).uri}`,
29
+ };
31
30
 
32
31
  useEffect(() => {
33
- component?.addChild?.(id.testID || id.accessibilityLabel);
32
+ component?.addChildren?.(test.accessibilityLabel, 'add');
33
+ return () => component?.addChildren(test.accessibilityLabel, 'remove');
34
34
  }, []);
35
35
 
36
36
  /**
@@ -54,37 +54,45 @@ const Image: React.FC<ImageProps> = ({
54
54
  };
55
55
 
56
56
  return (
57
- <FastImage
58
- {...rest}
59
- {...id}
60
- source={source}
61
- style={[styles.container, style]}
62
- onProgress={() => {
63
- error.current = false;
64
- if (status !== 'loading' && loading) {
65
- setStatus('loading');
66
- }
67
- }}
68
- onLoadStart={() => {
69
- error.current = false;
70
- }}
71
- onLoad={() => {
72
- error.current = false;
73
- }}
74
- onLoadEnd={() => {
75
- let current: Status = 'success';
76
- if (error.current) {
77
- current = 'error';
78
- }
79
- if (status !== current) {
80
- setStatus(current);
81
- }
82
- }}
83
- onError={() => {
84
- error.current = true;
57
+ <ComponentContext.Provider
58
+ value={{
59
+ componentName: 'Image',
60
+ params,
61
+ state: loading ? 'loading' : 'loaded',
62
+ componentId: test.accessibilityLabel,
85
63
  }}>
86
- {renderContent()}
87
- </FastImage>
64
+ <FastImage
65
+ {...rest}
66
+ {...test}
67
+ source={source}
68
+ style={[styles.container, style]}
69
+ onProgress={() => {
70
+ error.current = false;
71
+ if (status !== 'loading' && loading) {
72
+ setStatus('loading');
73
+ }
74
+ }}
75
+ onLoadStart={() => {
76
+ error.current = false;
77
+ }}
78
+ onLoad={() => {
79
+ error.current = false;
80
+ }}
81
+ onLoadEnd={() => {
82
+ let current: Status = 'success';
83
+ if (error.current) {
84
+ current = 'error';
85
+ }
86
+ if (status !== current) {
87
+ setStatus(current);
88
+ }
89
+ }}
90
+ onError={() => {
91
+ error.current = true;
92
+ }}>
93
+ {renderContent()}
94
+ </FastImage>
95
+ </ComponentContext.Provider>
88
96
  );
89
97
  };
90
98
 
package/Image/types.ts CHANGED
@@ -3,4 +3,5 @@ import {FastImageProps} from 'react-native-fast-image';
3
3
  export interface ImageProps extends FastImageProps {
4
4
  loading?: boolean;
5
5
  accessibilityLabel?: string;
6
+ params?: any;
6
7
  }
package/Input/Input.tsx CHANGED
@@ -14,7 +14,6 @@ import {InputProps} from './index';
14
14
  import {Icon} from '../Icon';
15
15
  import {checkTyping} from './utils';
16
16
  import {Loader} from '../Loader';
17
- import {formatComponentName} from '../Application/utils';
18
17
 
19
18
  const Input = forwardRef(
20
19
  (
@@ -212,7 +211,7 @@ const Input = forwardRef(
212
211
  value={{
213
212
  componentName: 'Input',
214
213
  params,
215
- componentLabel: formatComponentName(floatingValue || ''),
214
+ componentLabel: floatingValue,
216
215
  state: inputState,
217
216
  componentId: accessibilityLabel,
218
217
  }}>
@@ -7,7 +7,6 @@ import {InputDropDownProps} from './index';
7
7
  import {Icon} from '../Icon';
8
8
  import {Loader} from '../Loader';
9
9
  import {Styles} from '../Consts';
10
- import {formatComponentName} from '../Application/utils';
11
10
 
12
11
  const InputDropDown = ({
13
12
  value,
@@ -86,7 +85,6 @@ const InputDropDown = ({
86
85
  accessibilityLabel={accessibilityLabel}
87
86
  onPressIn={onPress}
88
87
  editable={false}
89
- textAlignVertical="top"
90
88
  style={[
91
89
  styles.input,
92
90
  {
@@ -110,10 +108,10 @@ const InputDropDown = ({
110
108
  return (
111
109
  <ComponentContext.Provider
112
110
  value={{
113
- componentName: 'InputOTP',
111
+ componentName: 'InputDropDown',
114
112
  params,
115
113
  state: 'enabled',
116
- componentLabel: formatComponentName(floatingValue || ''),
114
+ componentLabel: floatingValue,
117
115
  componentId: accessibilityLabel,
118
116
  }}>
119
117
  <TouchableOpacity
@@ -18,7 +18,6 @@ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
18
18
  import {InputMoneyProps} from './index';
19
19
  import {Icon} from '../Icon';
20
20
  import {formatMoneyToNumber, formatNumberToMoney} from './utils';
21
- import {formatComponentName} from '../Application/utils';
22
21
 
23
22
  const InputMoney = forwardRef(
24
23
  (
@@ -119,7 +118,6 @@ const InputMoney = forwardRef(
119
118
  {...props}
120
119
  accessibilityLabel={accessibilityLabel}
121
120
  editable={!disabled}
122
- textAlignVertical="top"
123
121
  ref={inputRef}
124
122
  keyboardType={'number-pad'}
125
123
  style={[
@@ -173,7 +171,7 @@ const InputMoney = forwardRef(
173
171
  value={{
174
172
  componentName: 'InputMoney',
175
173
  params,
176
- componentLabel: formatComponentName(floatingValue || ''),
174
+ componentLabel: floatingValue,
177
175
  state: inputState,
178
176
  componentId: accessibilityLabel,
179
177
  }}>
@@ -21,7 +21,6 @@ import styles from './styles';
21
21
  import {ErrorView, getBorderColor} from './common';
22
22
  import {ApplicationContext, ComponentContext} from '../Application';
23
23
  import {Spacing} from '../Consts';
24
- import {formatComponentName} from '../Application/utils';
25
24
 
26
25
  const OTPCaret: FC<CaretProps> = ({index, length}) => {
27
26
  const DURATION = 300;
@@ -229,7 +228,7 @@ const InputOTP = forwardRef(
229
228
  value={{
230
229
  componentName: 'InputOTP',
231
230
  params,
232
- componentLabel: formatComponentName(floatingValue || ''),
231
+ componentLabel: floatingValue,
233
232
  state: 'enabled',
234
233
  componentId: accessibilityLabel,
235
234
  }}>
@@ -7,7 +7,6 @@ import {Text} from '../Text';
7
7
  import {ApplicationContext, MiniAppContext} from '../Application';
8
8
  import {Button} from '../Button';
9
9
  import {Icon} from '../Icon';
10
- import {getAccessibilityID} from '../Application/utils';
11
10
 
12
11
  const PopupNotify: React.FC<PopupNotifyProps> = ({
13
12
  id,
@@ -163,7 +162,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
163
162
  const buildCloseIcon = () => {
164
163
  return (
165
164
  <TouchableOpacity
166
- {...getAccessibilityID?.('ic_popup_close')}
165
+ accessibilityLabel={'ic_popup_close'}
167
166
  style={styles.iconCloseContainer}
168
167
  onPress={() => {
169
168
  closeAction.current = 'icon_close';
@@ -189,7 +188,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
189
188
 
190
189
  return (
191
190
  <View
192
- {...getAccessibilityID?.(`pu_${context.code}_notify`)}
191
+ accessibilityLabel={'PopupNotify'}
193
192
  style={[
194
193
  styles.container,
195
194
  {backgroundColor: theme.colors.background.surface},
@@ -5,7 +5,6 @@ import {ApplicationContext, MiniAppContext} from '../Application';
5
5
  import {Image} from '../Image';
6
6
  import {Radius, Spacing} from '../Consts';
7
7
  import {Icon} from '../Icon';
8
- import {getAccessibilityID} from '../Application/utils';
9
8
 
10
9
  const PopupPromotion: React.FC<PopupPromotionProps> = ({
11
10
  id,
@@ -51,10 +50,9 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
51
50
  */
52
51
  const buildCloseIcon = () => {
53
52
  return (
54
- <View
55
- {...getAccessibilityID?.('ic_popup_close')}
56
- style={styles.iconCloseContainer}>
53
+ <View style={styles.iconCloseContainer}>
57
54
  <TouchableOpacity
55
+ accessibilityLabel={'ic_popup_close'}
58
56
  onPress={() => {
59
57
  closeAction.current = 'icon_close';
60
58
  navigator?.pop();
@@ -81,7 +79,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
81
79
  };
82
80
 
83
81
  return (
84
- <View {...getAccessibilityID?.(`pu_${context.code}_promotion`)}>
82
+ <View accessibilityLabel={'PopupPromotion'}>
85
83
  <Image
86
84
  source={{
87
85
  uri: image,
package/Radio/index.tsx CHANGED
@@ -43,12 +43,12 @@ const Radio: FC<RadioProps> = ({
43
43
  return (
44
44
  <ComponentContext.Provider
45
45
  value={{
46
- componentName: 'Button',
46
+ componentName: 'Radio',
47
47
  params,
48
48
  state: disabled ? 'disabled' : 'enabled',
49
49
  componentId: accessibilityLabel,
50
50
  componentLabel: formatNameLength(label || ''),
51
- componentValue: value,
51
+ componentValue: selected,
52
52
  action: 'click',
53
53
  }}>
54
54
  <TouchableOpacity
package/Switch/index.tsx CHANGED
@@ -24,7 +24,7 @@ const Switch: FC<SwitchProps> = ({
24
24
  return (
25
25
  <ComponentContext.Provider
26
26
  value={{
27
- componentName: 'Button',
27
+ componentName: 'Switch',
28
28
  params,
29
29
  state: disabled ? 'disabled' : 'enabled',
30
30
  componentId: accessibilityLabel,
package/Title/index.tsx CHANGED
@@ -22,8 +22,10 @@ const Title: FC<TitleProps> = ({
22
22
  badgeLabel,
23
23
  buttonTitle,
24
24
  onPressRightAction = () => {},
25
+ onPressTrailingAction = () => {},
25
26
  buttonSize = 'small',
26
27
  textOnly = false,
28
+ style,
27
29
  }) => {
28
30
  const {theme} = useContext(ApplicationContext);
29
31
  const [badgeWidth, setBadgeWidth] = useState(0);
@@ -90,18 +92,23 @@ const Title: FC<TitleProps> = ({
90
92
  )}
91
93
  {renderActionLeft()}
92
94
  </View>
93
- <Text
94
- color={theme.colors.text.secondary}
95
- typography={'description_default_regular'}>
96
- {description}
97
- </Text>
95
+ {description && (
96
+ <Text
97
+ style={styles.description}
98
+ color={theme.colors.text.secondary}
99
+ typography={'description_default_regular'}>
100
+ {description}
101
+ </Text>
102
+ )}
98
103
  </View>
99
104
  );
100
105
  };
101
106
 
102
107
  const renderActionLeft = () => {
103
108
  return (
104
- <View style={styles.iconLeftView}>
109
+ <TouchableOpacity
110
+ onPress={onPressTrailingAction}
111
+ style={styles.iconLeftView}>
105
112
  {showTrailingAction && !showRightAction && (
106
113
  <View
107
114
  style={[
@@ -119,7 +126,7 @@ const Title: FC<TitleProps> = ({
119
126
  />
120
127
  </View>
121
128
  )}
122
- </View>
129
+ </TouchableOpacity>
123
130
  );
124
131
  };
125
132
 
@@ -129,7 +136,8 @@ const Title: FC<TitleProps> = ({
129
136
  return (
130
137
  <View>
131
138
  {!buttonTitle ? (
132
- <View
139
+ <TouchableOpacity
140
+ onPress={onPressRightAction}
133
141
  style={[
134
142
  styles.iconRight,
135
143
  {
@@ -141,7 +149,7 @@ const Title: FC<TitleProps> = ({
141
149
  size={scaleSize(22)}
142
150
  color={theme.colors.primary}
143
151
  />
144
- </View>
152
+ </TouchableOpacity>
145
153
  ) : (
146
154
  <TouchableOpacity onPress={onPressRightAction}>
147
155
  <Text color={theme.colors.primary} typography={buttonTypo}>
@@ -166,7 +174,7 @@ const Title: FC<TitleProps> = ({
166
174
  }
167
175
 
168
176
  return (
169
- <View style={[styles.wrapper, isSection && styles.margin]}>
177
+ <View style={[style, styles.wrapper, isSection && styles.margin]}>
170
178
  {renderIcon()}
171
179
  {renderContent()}
172
180
  {renderActionRight()}
package/Title/styles.ts CHANGED
@@ -68,9 +68,12 @@ export default StyleSheet.create({
68
68
  contentView: {marginRight: Spacing.S, flex: 1},
69
69
  title: {
70
70
  fontWeight: 'bold',
71
- marginBottom: Spacing.XS,
71
+ color: Colors.black_17,
72
72
  },
73
73
  badge: {
74
74
  marginLeft: Spacing.XS,
75
75
  },
76
+ description: {
77
+ marginTop: Spacing.XS,
78
+ },
76
79
  });
package/Title/types.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import {ViewStyle} from 'react-native';
2
+
1
3
  export type TitleProps = {
2
4
  type?: 'card' | 'section';
3
5
  size?: 'small' | 'medium' | 'large';
@@ -12,5 +14,7 @@ export type TitleProps = {
12
14
  buttonTitle?: string;
13
15
  buttonSize?: 'small' | 'large';
14
16
  onPressRightAction?: () => void;
17
+ onPressTrailingAction?: () => void;
15
18
  textOnly?: boolean;
19
+ style?: ViewStyle;
16
20
  };
package/code-scanner.js CHANGED
@@ -1,51 +1,143 @@
1
1
  const scanner = require('react-scanner');
2
+ const fs = require('fs');
2
3
  const path = require('path');
3
4
 
4
- const scan = async config => {
5
- return await scanner.run(config);
5
+ const scan = async (config) => {
6
+ return await scanner.run(config);
6
7
  };
7
8
 
8
- const calcSum = array => {
9
- return array.reduce((a, b) => a + b, 0);
9
+ const calcSum = (array) => {
10
+ return array.reduce((a, b) => a + b, 0);
10
11
  };
11
12
 
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);
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
+ }
21
34
  };
22
35
 
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
+
23
73
  const main = async () => {
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);
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
+ }
49
141
  };
50
142
 
51
- main().catch(console.error);
143
+ main();
@@ -0,0 +1,56 @@
1
+ const {readFileSync, writeFileSync, readdirSync, statSync} = require('fs');
2
+ const path = require('path');
3
+ let rootPath = process.argv[2];
4
+
5
+ const migrateText = [
6
+ {typo1: 'headline_s', typo2: 'headline_default_bold'},
7
+ {typo1: 'header_s', typo2: 'header_s_semibold'},
8
+ {typo1: 'header_xs', typo2: 'header_xs_semibold'},
9
+ {typo1: 'description_default', typo2: 'body_default_regular'},
10
+ {typo1: 'description_s', typo2: 'description_default_regular'},
11
+ {typo1: 'description_xs', typo2: 'description_xs_regular'},
12
+ {typo1: 'label_default', typo2: 'label_default_medium'},
13
+ {typo1: 'label_s', typo2: 'label_s_medium'},
14
+ {typo1: 'label_xs', typo2: 'label_xs_medium'},
15
+ {typo1: 'action_default', typo2: 'action_default_bold'},
16
+ {typo1: 'action_xs', typo2: 'action_xs_bold'},
17
+ {typo1: 'action_xxs', typo2: 'action_xxs_bold'},
18
+ ];
19
+
20
+ function replaceTextInFile(oldText, newText, filePath) {
21
+ try {
22
+ let content = readFileSync(filePath, {encoding: 'utf-8'});
23
+ const regex = new RegExp(`\\b${oldText}\\b`, 'g');
24
+ content = content.replace(regex, newText);
25
+ writeFileSync(filePath, content, 'utf8');
26
+ console.log(`Replaced text in: ${filePath}`);
27
+ } catch (error) {
28
+ console.error(`Error processing file ${filePath}:`, error);
29
+ }
30
+ }
31
+
32
+ function scanDirectory(directory, oldText, newText) {
33
+ const files = readdirSync(directory);
34
+
35
+ files.forEach(file => {
36
+ const filePath = path.join(directory, file);
37
+ const stat = statSync(filePath);
38
+
39
+ if (stat.isDirectory()) {
40
+ scanDirectory(filePath, oldText, newText);
41
+ } else if (
42
+ stat.isFile() &&
43
+ (filePath.endsWith('.tsx') || filePath.endsWith('.ts'))
44
+ ) {
45
+ replaceTextInFile(oldText, newText, filePath);
46
+ }
47
+ });
48
+ }
49
+
50
+ function main() {
51
+ migrateText.forEach(({typo1, typo2}) => {
52
+ scanDirectory(rootPath, typo1, typo2);
53
+ });
54
+ }
55
+
56
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.92.3-tracking.2",
3
+ "version": "0.92.3-tracking.21",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {