@momo-kits/foundation 0.81.18 → 0.81.20

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.
@@ -7,6 +7,7 @@ import {
7
7
  StyleSheet,
8
8
  TouchableOpacity,
9
9
  View,
10
+ ViewStyle,
10
11
  } from 'react-native';
11
12
  import {ApplicationContext} from './index';
12
13
  import {Colors, Radius, Spacing, Styles} from '../Consts';
@@ -28,7 +29,6 @@ const styles = StyleSheet.create({
28
29
  height: 28,
29
30
  width: 28,
30
31
  borderRadius: 14,
31
- borderColor: '#00000066',
32
32
  justifyContent: 'center',
33
33
  alignItems: 'center',
34
34
  },
@@ -92,25 +92,23 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
92
92
  icon,
93
93
  tintColor,
94
94
  onPress,
95
- backgroundColor,
96
95
  useBorder = true,
97
96
  accessibilityLabel,
98
97
  }) => {
99
98
  const {theme} = useContext(ApplicationContext);
100
- if (!backgroundColor && tintColor != Colors.black_01) {
101
- backgroundColor = theme.colors.background.surface;
99
+ let buttonStyle: ViewStyle = {backgroundColor: '#00000066'};
100
+ if (tintColor != Colors.black_01) {
101
+ buttonStyle = {
102
+ backgroundColor: 'transparent',
103
+ borderColor: '#00000066',
104
+ borderWidth: useBorder ? 0.5 : 0,
105
+ };
102
106
  }
103
107
 
104
108
  return (
105
109
  <TouchableOpacity
106
110
  accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
107
- style={[
108
- styles.navigationButton,
109
- {
110
- backgroundColor: backgroundColor ?? '#00000066',
111
- borderWidth: useBorder && backgroundColor ? 0.5 : 0,
112
- },
113
- ]}
111
+ style={[styles.navigationButton, buttonStyle]}
114
112
  onPress={onPress}>
115
113
  <Icon
116
114
  source={icon}
@@ -146,7 +144,6 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
146
144
  preventBack,
147
145
  onPressLeftHeader,
148
146
  useBorder,
149
- backgroundColor,
150
147
  accessibilityLabel = '',
151
148
  }) => {
152
149
  const {navigator} = useContext(ApplicationContext);
@@ -214,7 +211,6 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
214
211
  onPress={goBack}
215
212
  accessibilityLabel={`${accessibilityLabel}Back`}
216
213
  useBorder={useBorder}
217
- backgroundColor={backgroundColor}
218
214
  />
219
215
  </View>
220
216
  );
@@ -43,7 +43,7 @@ const ModalScreen: React.FC<any> = props => {
43
43
 
44
44
  const Modal: React.FC<ModalParams> = props => {
45
45
  const {theme, navigator} = useContext(ApplicationContext);
46
- const {screen, barrierDismissible, modalName} = props.route.params;
46
+ const {screen, barrierDismissible} = props.route.params;
47
47
  const Component = useRef(screen).current;
48
48
  const navigation = new Navigation(props.navigation, theme);
49
49
  const params = {
@@ -53,49 +53,10 @@ const Modal: React.FC<ModalParams> = props => {
53
53
 
54
54
  delete params.screen;
55
55
 
56
- const getTrackingInfo = () => {
57
- const routes = props.navigation.getState()?.routes || [];
58
- const routesLength = routes.length;
59
- let screen_name = routes?.[0]?.params?.screen?.name;
60
- if (routesLength > 1) {
61
- screen_name = routes[routesLength - 2]?.params?.screen?.name;
62
- }
63
- const error_code = screen?.({params: {}})?.props?.error;
64
- return {
65
- feature_code: navigator?.trackingInfo?.code,
66
- app_id: navigator?.trackingInfo?.appId,
67
- miniapp_version: navigator?.trackingInfo?.buildNumber,
68
- flow_partner_id: navigator?.trackingInfo?.flowPartnerId,
69
- screen_name,
70
- component_type: 'popup',
71
- component_name: modalName,
72
- error_code,
73
- };
74
- };
75
-
76
- /**
77
- * tracking
78
- */
79
- useEffect(() => {
80
- if (navigator?.trackingInfo) {
81
- navigator?.maxApi?.trackEvent('service_component_displayed', {
82
- ...getTrackingInfo(),
83
- trigger_id: '111012100000000000',
84
- });
85
- }
86
- }, []);
87
-
88
56
  const onDismiss = () => {
89
57
  if (barrierDismissible) {
90
58
  return;
91
59
  }
92
- if (navigator?.trackingInfo) {
93
- navigator?.maxApi?.trackEvent('service_popup_dismissed', {
94
- ...getTrackingInfo(),
95
- action_type: 'touch_outside',
96
- trigger_id: '111154100000000001',
97
- });
98
- }
99
60
  navigator?.pop();
100
61
  };
101
62
 
@@ -239,7 +200,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
239
200
  <HeaderLeft
240
201
  {...props}
241
202
  useBorder={false}
242
- backgroundColor="transparent"
243
203
  accessibilityLabel={'BottomSheet/'}
244
204
  />
245
205
  );
@@ -265,7 +225,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
265
225
  <NavigationButton
266
226
  {...props}
267
227
  icon="24_navigation_close"
268
- backgroundColor="transparent"
269
228
  useBorder={false}
270
229
  onPress={() => bottomSheetRef.current?.dismiss()}
271
230
  accessibilityLabel={'BottomSheet/Close'}
@@ -110,7 +110,6 @@ export type ScreenParams = {
110
110
 
111
111
  export interface ModalParams extends ScreenParams {
112
112
  [key: string]: any;
113
- modalName?: string;
114
113
  onDismiss?: () => void;
115
114
  barrierDismissible?: boolean;
116
115
  }
@@ -124,7 +123,6 @@ export interface BottomSheetParams extends ScreenParams {
124
123
  export type NavigationButtonProps = {
125
124
  icon: string;
126
125
  tintColor?: string;
127
- backgroundColor?: string;
128
126
  useBorder?: boolean;
129
127
  onPress: () => void;
130
128
  accessibilityLabel?: string;
package/Input/Input.tsx CHANGED
@@ -21,18 +21,18 @@ const Input = forwardRef(
21
21
  onChangeText,
22
22
  floatingValue,
23
23
  floatingIcon,
24
- size,
24
+ size = 'small',
25
25
  placeholder,
26
26
  onBlur,
27
27
  onFocus,
28
28
  errorMessage,
29
29
  icon,
30
- disabled,
30
+ disabled = false,
31
31
  floatingIconColor,
32
32
  iconColor,
33
- required,
33
+ required = false,
34
34
  errorSpacing,
35
- loading,
35
+ loading = false,
36
36
  leadingIcon,
37
37
  leadingIconColor,
38
38
  fontWeight = 'Regular',
@@ -165,8 +165,4 @@ const Input = forwardRef(
165
165
  },
166
166
  );
167
167
 
168
- Input.defaultProps = {
169
- size: 'small',
170
- };
171
-
172
168
  export default Input;
@@ -12,17 +12,17 @@ const InputDropDown = ({
12
12
  value,
13
13
  floatingValue,
14
14
  floatingIcon,
15
- size,
15
+ size = 'small',
16
16
  onPress,
17
17
  placeholder,
18
18
  errorMessage,
19
19
  icon = 'arrow_chevron_down_small',
20
- disabled,
20
+ disabled = false,
21
21
  floatingIconColor,
22
22
  iconColor,
23
- required,
23
+ required = false,
24
24
  errorSpacing,
25
- loading,
25
+ loading = false,
26
26
  leadingIcon,
27
27
  leadingIconColor,
28
28
  style,
@@ -116,8 +116,4 @@ const InputDropDown = ({
116
116
  );
117
117
  };
118
118
 
119
- InputDropDown.defaultProps = {
120
- size: 'small',
121
- };
122
-
123
119
  export default InputDropDown;
@@ -24,12 +24,13 @@ const InputMoney = forwardRef(
24
24
  onFocus,
25
25
  errorMessage,
26
26
  icon,
27
- disabled,
27
+ disabled = false,
28
28
  floatingIconColor,
29
29
  iconColor,
30
- required,
30
+ required = false,
31
31
  errorSpacing,
32
32
  style,
33
+ defaultValue = '',
33
34
  ...props
34
35
  }: InputMoneyProps,
35
36
  ref,
@@ -37,20 +38,26 @@ const InputMoney = forwardRef(
37
38
  const {theme} = useContext(ApplicationContext);
38
39
  const [focused, setFocused] = useState(false);
39
40
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
40
- const [value, setValue] = useState('');
41
41
  const accessibilityLabel = `InputMoney/${floatingValue}`;
42
42
 
43
+ const validateText = (text: string) => {
44
+ const valueFormat = formatMoneyToNumber(text, 'đ');
45
+ return formatNumberToMoney(valueFormat, 'đ');
46
+ };
47
+
48
+ const [value, setValue] = useState(validateText(defaultValue));
49
+
43
50
  const onClearText = () => {
44
51
  inputRef?.current?.clear();
45
52
  setValue('');
46
53
  onChangeText?.('');
47
54
  };
55
+
48
56
  const _onChangeText = (text: string) => {
49
57
  if (text.length < value.length && value.indexOf(text) === 0) {
50
58
  text = value.slice(0, -2) + 'đ';
51
59
  }
52
- const valueFormat = formatMoneyToNumber(text, 'đ');
53
- setValue(formatNumberToMoney(valueFormat, 'đ'));
60
+ setValue(validateText(text));
54
61
  onChangeText?.(formatMoneyToNumber(text, 'đ').toString());
55
62
  };
56
63
 
@@ -29,12 +29,12 @@ const InputTextArea = forwardRef(
29
29
  floatingValue,
30
30
  onFocus,
31
31
  onBlur,
32
- disabled,
32
+ disabled = false,
33
33
  value,
34
34
  defaultValue,
35
35
  height,
36
36
  placeholder,
37
- maxLength,
37
+ maxLength = MAX_LENGTH,
38
38
  required,
39
39
  errorSpacing,
40
40
  style,
@@ -158,8 +158,4 @@ const InputTextArea = forwardRef(
158
158
  },
159
159
  );
160
160
 
161
- InputTextArea.defaultProps = {
162
- maxLength: MAX_LENGTH,
163
- };
164
-
165
161
  export default InputTextArea;
package/Input/index.tsx CHANGED
@@ -85,10 +85,6 @@ type InputPropsWithoutSizeAndIcon = Omit<
85
85
  'size' | 'icon' | 'iconColor'
86
86
  >;
87
87
 
88
- type InputPropsOmitForSearch = Omit<
89
- InputProps,
90
- 'required' | 'size' | 'errorMessage' | 'disabled'
91
- >;
92
88
  type InputPropsWithoutPlaceholder = Omit<InputProps, 'placeholder'>;
93
89
 
94
90
  export interface InputTextAreaProps extends InputPropsWithoutSizeAndIcon {
@@ -99,7 +95,7 @@ export interface InputTextAreaProps extends InputPropsWithoutSizeAndIcon {
99
95
  height?: number;
100
96
  }
101
97
 
102
- export interface InputSearchProps extends InputPropsOmitForSearch {
98
+ export interface InputSearchProps extends TextInputProps {
103
99
  /**
104
100
  * Optional. Represents the text to be displayed on the search button within the InputSearch component.
105
101
  */
@@ -118,6 +114,16 @@ export interface InputSearchProps extends InputPropsOmitForSearch {
118
114
  showBorder?: boolean;
119
115
 
120
116
  onPressButtonText?: () => void;
117
+
118
+ /**
119
+ * Optional. Represents the color of the icon in the Input component.
120
+ */
121
+ iconColor?: string;
122
+
123
+ /**
124
+ * Optional. Represents the name or key of the icon to be displayed in the Input component.
125
+ */
126
+ icon?: string;
121
127
  }
122
128
 
123
129
  export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
package/Layout/Screen.tsx CHANGED
@@ -267,6 +267,7 @@ const Screen = forwardRef(
267
267
  <KeyboardAvoidingView
268
268
  style={Styles.flex}
269
269
  enabled={enableKeyboardAvoidingView}
270
+ keyboardVerticalOffset={heightHeader - 20}
270
271
  behavior={Platform.select({
271
272
  ios: 'padding',
272
273
  android: undefined,
@@ -1,4 +1,4 @@
1
- import React, {useContext, useState} from 'react';
1
+ import React, {useContext, useEffect, useRef, useState} from 'react';
2
2
  import {ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native';
3
3
  import {PopupNotifyProps} from './types';
4
4
  import {Radius, Spacing, Styles} from '../Consts';
@@ -20,6 +20,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
20
20
  }) => {
21
21
  const {theme, navigator, translate} = useContext(ApplicationContext);
22
22
  const [scrollContent, setScrollContent] = useState(false);
23
+ const closeAction = useRef('touch_outside');
23
24
 
24
25
  let descriptionStyle = {};
25
26
  let Description: any = View;
@@ -28,6 +29,19 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
28
29
  descriptionStyle = {height: 80};
29
30
  }
30
31
 
32
+ /**
33
+ * tracking
34
+ */
35
+ useEffect(() => {
36
+ onTracking('service_component_displayed', undefined, '111012100000000000');
37
+ return () => {
38
+ onTracking(
39
+ 'service_popup_dismissed',
40
+ closeAction.current,
41
+ '111154100000000001',
42
+ );
43
+ };
44
+ }, []);
31
45
  /**
32
46
  * on action popup
33
47
  * @param callback
@@ -37,7 +51,11 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
37
51
  callback?.();
38
52
  };
39
53
 
40
- const onTracking = (actionType: string) => {
54
+ const onTracking = (
55
+ event: string,
56
+ actionType: string | undefined,
57
+ trigger_id: string,
58
+ ) => {
41
59
  if (navigator?.trackingInfo) {
42
60
  const routes = navigator.ref.current?.getRootState()?.routes || [];
43
61
  const routesLength = routes.length;
@@ -45,7 +63,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
45
63
  if (routesLength > 1) {
46
64
  screen_name = routes[routesLength - 2]?.params?.screen?.name;
47
65
  }
48
- navigator?.maxApi?.trackEvent('service_popup_dismissed', {
66
+ navigator?.maxApi?.trackEvent(event, {
49
67
  feature_code: navigator?.trackingInfo?.code,
50
68
  app_id: navigator?.trackingInfo?.appId,
51
69
  miniapp_version: navigator?.trackingInfo?.buildNumber,
@@ -54,7 +72,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
54
72
  component_type: 'popup',
55
73
  component_name: 'PopupNotify',
56
74
  error_code: error,
57
- trigger_id: '111154100000000001',
75
+ trigger_id,
58
76
  action_type: actionType,
59
77
  });
60
78
  }
@@ -75,7 +93,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
75
93
  type="text"
76
94
  size="medium"
77
95
  onPress={() => {
78
- onTracking('button_action');
96
+ closeAction.current = 'button_action';
79
97
  onAction(secondary?.onPress);
80
98
  }}
81
99
  />
@@ -88,7 +106,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
88
106
  title={primary.title}
89
107
  size="medium"
90
108
  onPress={() => {
91
- onTracking('button_action');
109
+ closeAction.current = 'button_action';
92
110
  onAction(primary.onPress);
93
111
  }}
94
112
  />
@@ -103,7 +121,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
103
121
  title={primary.title}
104
122
  size="medium"
105
123
  onPress={() => {
106
- onTracking('button_action');
124
+ closeAction.current = 'button_action';
107
125
  onAction(primary.onPress);
108
126
  }}
109
127
  />
@@ -115,7 +133,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
115
133
  type="text"
116
134
  size="medium"
117
135
  onPress={() => {
118
- onTracking('button_action');
136
+ closeAction.current = 'button_action';
119
137
  onAction(secondary?.onPress);
120
138
  }}
121
139
  />
@@ -148,7 +166,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
148
166
  <TouchableOpacity
149
167
  style={styles.iconCloseContainer}
150
168
  onPress={() => {
151
- onTracking('icon_close');
169
+ closeAction.current = 'icon_close';
152
170
  onAction(onIconClose);
153
171
  }}>
154
172
  <View
@@ -1,4 +1,4 @@
1
- import React, {useContext} from 'react';
1
+ import React, {useContext, useEffect, useRef} from 'react';
2
2
  import {StyleSheet, TouchableOpacity, View} from 'react-native';
3
3
  import {PopupPromotionProps} from './types';
4
4
  import {ApplicationContext} from '../Application';
@@ -11,8 +11,27 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
11
11
  onIconClose,
12
12
  }) => {
13
13
  const {theme, navigator} = useContext(ApplicationContext);
14
+ const closeAction = useRef('touch_outside');
14
15
 
15
- const onTracking = (actionType: string) => {
16
+ /**
17
+ * tracking
18
+ */
19
+ useEffect(() => {
20
+ onTracking('service_component_displayed', undefined, '111012100000000000');
21
+ return () => {
22
+ onTracking(
23
+ 'service_popup_dismissed',
24
+ closeAction.current,
25
+ '111154100000000001',
26
+ );
27
+ };
28
+ }, []);
29
+
30
+ const onTracking = (
31
+ event: string,
32
+ actionType: string | undefined,
33
+ trigger_id: string,
34
+ ) => {
16
35
  if (navigator?.trackingInfo) {
17
36
  const routes = navigator.ref.current?.getRootState()?.routes || [];
18
37
  const routesLength = routes.length;
@@ -20,7 +39,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
20
39
  if (routesLength > 1) {
21
40
  screen_name = routes[routesLength - 2]?.params?.screen?.name;
22
41
  }
23
- navigator?.maxApi?.trackEvent('service_popup_dismissed', {
42
+ navigator?.maxApi?.trackEvent(event, {
24
43
  feature_code: navigator?.trackingInfo?.code,
25
44
  app_id: navigator?.trackingInfo?.appId,
26
45
  miniapp_version: navigator?.trackingInfo?.buildNumber,
@@ -28,7 +47,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
28
47
  screen_name,
29
48
  component_type: 'popup',
30
49
  component_name: 'PopupPromotion',
31
- trigger_id: '111154100000000001',
50
+ trigger_id,
32
51
  action_type: actionType,
33
52
  });
34
53
  }
@@ -42,7 +61,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
42
61
  <View style={styles.iconCloseContainer}>
43
62
  <TouchableOpacity
44
63
  onPress={() => {
45
- onTracking('icon_close');
64
+ closeAction.current = 'icon_close';
46
65
  navigator?.pop();
47
66
  onIconClose?.();
48
67
  }}
package/Title/index.tsx CHANGED
@@ -1,7 +1,9 @@
1
1
  import React, {FC, useContext, useState} from 'react';
2
2
  import {
3
3
  LayoutChangeEvent,
4
+ NativeSyntheticEvent,
4
5
  Text as RNText,
6
+ TextLayoutEventData,
5
7
  TouchableOpacity,
6
8
  View,
7
9
  } from 'react-native';
@@ -25,6 +27,7 @@ const Title: FC<TitleProps> = ({
25
27
  }) => {
26
28
  const {theme} = useContext(ApplicationContext);
27
29
  const [containerWidth, setContainerWidth] = useState(0);
30
+ const [textLines, setTextLines] = useState(0);
28
31
  const flexStyle = titleFlex ? {flex: 1} : {};
29
32
  const typeStyle =
30
33
  type === 'screen' ? styles.screen : styles[`${type}_${size}`];
@@ -38,7 +41,10 @@ const Title: FC<TitleProps> = ({
38
41
  const titleWeight = type === 'screen' ? 'Semibold' : 'Bold';
39
42
  const marginStyle = type === 'section' ? {marginTop: Spacing.M} : {};
40
43
  const numberOfLines = type === 'section' ? 1 : 2;
44
+
41
45
  const renderAction = () => {
46
+ if (!actionTitle && !titleFlex && textLines > 1) return null;
47
+
42
48
  return !!actionTitle && titleFlex ? (
43
49
  <TouchableOpacity onPress={onPressAction}>
44
50
  <Text typography={'action_s'} color={theme.colors.primary}>
@@ -66,6 +72,10 @@ const Title: FC<TitleProps> = ({
66
72
  setContainerWidth(e.nativeEvent.layout.width);
67
73
  };
68
74
 
75
+ const onTextLayout = (e: NativeSyntheticEvent<TextLayoutEventData>) => {
76
+ setTextLines(e.nativeEvent.lines.length);
77
+ };
78
+
69
79
  return (
70
80
  <View onLayout={onLayout} style={styles.wrapper}>
71
81
  <View style={[styles.container, marginStyle]}>
@@ -73,6 +83,7 @@ const Title: FC<TitleProps> = ({
73
83
  <Icon style={styles.icon} source={icon} />
74
84
  )}
75
85
  <RNText
86
+ onTextLayout={onTextLayout}
76
87
  numberOfLines={numberOfLines}
77
88
  style={[
78
89
  typeStyle,
package/Title/styles.ts CHANGED
@@ -32,11 +32,10 @@ export default StyleSheet.create({
32
32
  lineHeight: scaleSize(44),
33
33
  },
34
34
  title: {
35
- marginRight: Spacing.XS,
35
+ marginRight: Spacing.S,
36
36
  },
37
37
  container: {
38
38
  flexDirection: 'row',
39
- alignItems: 'baseline',
40
39
  width: '100%',
41
40
  },
42
41
  actionIcon: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.81.18",
3
+ "version": "0.81.20",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {