@momo-kits/foundation 0.89.4-react-native.0.74.1 → 0.89.4-tracking.15

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.
@@ -9,6 +9,11 @@ import {ApplicationContext} 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
+
14
+ const {
15
+ ScreenContext,
16
+ } = require('react-native/Libraries/Components/ScreenContext');
12
17
 
13
18
  export interface IconButtonProps extends TouchableOpacityProps {
14
19
  /**
@@ -26,6 +31,10 @@ export interface IconButtonProps extends TouchableOpacityProps {
26
31
  * Optional. Defines the size of the IconButton.
27
32
  */
28
33
  size?: 'large' | 'small';
34
+
35
+ params?: any;
36
+
37
+ componentId?: string;
29
38
  }
30
39
 
31
40
  const IconButton: React.FC<IconButtonProps> = ({
@@ -33,9 +42,12 @@ const IconButton: React.FC<IconButtonProps> = ({
33
42
  icon,
34
43
  size,
35
44
  onPress,
45
+ params,
46
+ componentId,
36
47
  ...rest
37
48
  }) => {
38
49
  const {theme} = useContext(ApplicationContext);
50
+ const screenInfo = useContext<any>(ScreenContext);
39
51
 
40
52
  /**
41
53
  * get size icon button
@@ -121,13 +133,24 @@ const IconButton: React.FC<IconButtonProps> = ({
121
133
  const iconSize = size === 'small' ? 16 : 24;
122
134
 
123
135
  return (
124
- <TouchableOpacity
125
- {...rest}
126
- activeOpacity={activeOpacity}
127
- onPress={onPressButton}
128
- style={buttonStyle}>
129
- <Icon size={iconSize} source={icon} color={getIconColor()} />
130
- </TouchableOpacity>
136
+ <ScreenContext.Provider
137
+ value={{
138
+ ...screenInfo,
139
+ componentName: 'IconButton',
140
+ params,
141
+ state: type === 'disabled' ? 'disabled' : 'enabled',
142
+ componentId,
143
+ componentValue: formatComponentName(icon),
144
+ action: 'click',
145
+ }}>
146
+ <TouchableOpacity
147
+ {...rest}
148
+ activeOpacity={activeOpacity}
149
+ onPress={onPressButton}
150
+ style={buttonStyle}>
151
+ <Icon size={iconSize} source={icon} color={getIconColor()} />
152
+ </TouchableOpacity>
153
+ </ScreenContext.Provider>
131
154
  );
132
155
  };
133
156
 
package/Image/index.tsx CHANGED
@@ -1,13 +1,12 @@
1
1
  import React, {useContext, useRef, useState} from 'react';
2
2
  import {StyleSheet, View} from 'react-native';
3
-
3
+ import FastImage from 'react-native-fast-image';
4
4
  import styles from './styles';
5
5
  import {ApplicationContext} from '../Application';
6
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 FastImage from 'react-native-fast-image';
11
10
 
12
11
  type Status = 'success' | 'loading' | 'error';
13
12
 
package/Input/Input.tsx CHANGED
@@ -13,6 +13,11 @@ import {InputProps} from './index';
13
13
  import {Icon} from '../Icon';
14
14
  import {checkTyping} from './utils';
15
15
  import {Loader} from '../Loader';
16
+ import {formatComponentName} from '../Application/utils';
17
+
18
+ const {
19
+ ScreenContext,
20
+ } = require('react-native/Libraries/Components/ScreenContext');
16
21
 
17
22
  const Input = forwardRef(
18
23
  (
@@ -39,6 +44,8 @@ const Input = forwardRef(
39
44
  onPressIcon,
40
45
  secureTextEntry,
41
46
  style,
47
+ params,
48
+ componentId,
42
49
  ...props
43
50
  }: InputProps,
44
51
  ref,
@@ -48,6 +55,7 @@ const Input = forwardRef(
48
55
  const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
49
56
  const [secureTextInput, setSecureTextInput] = useState(secureTextEntry);
50
57
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
58
+ const screenInfo = useContext<any>(ScreenContext);
51
59
 
52
60
  const onClearText = () => {
53
61
  inputRef?.current?.clear();
@@ -180,11 +188,34 @@ const Input = forwardRef(
180
188
  );
181
189
  };
182
190
 
191
+ let inputState = 'active';
192
+
193
+ if (value && value?.length > 0) {
194
+ inputState = 'filled';
195
+ }
196
+ if (errorMessage && errorMessage?.length > 0) {
197
+ inputState = 'error';
198
+ }
199
+
200
+ if (disabled) {
201
+ inputState = 'disabled';
202
+ }
203
+
183
204
  return (
184
- <View style={[style, styles.wrapper]}>
185
- {renderInputView()}
186
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
187
- </View>
205
+ <ScreenContext.Provider
206
+ value={{
207
+ ...screenInfo,
208
+ componentName: 'Input',
209
+ params,
210
+ componentLabel: formatComponentName(floatingValue || ''),
211
+ state: inputState,
212
+ componentId,
213
+ }}>
214
+ <View style={[style, styles.wrapper]}>
215
+ {renderInputView()}
216
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
217
+ </View>
218
+ </ScreenContext.Provider>
188
219
  );
189
220
  },
190
221
  );
@@ -7,6 +7,11 @@ 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
+
12
+ const {
13
+ ScreenContext,
14
+ } = require('react-native/Libraries/Components/ScreenContext');
10
15
 
11
16
  const InputDropDown = ({
12
17
  value,
@@ -26,10 +31,13 @@ const InputDropDown = ({
26
31
  leadingIcon,
27
32
  leadingIconColor,
28
33
  style,
34
+ params,
35
+ componentId,
29
36
  ...props
30
37
  }: InputDropDownProps) => {
31
38
  const {theme} = useContext(ApplicationContext);
32
39
  const full = !!value || !!placeholder;
40
+ const screenInfo = useContext<any>(ScreenContext);
33
41
 
34
42
  const renderIcon = (color: string | undefined) => {
35
43
  if (loading) {
@@ -104,10 +112,22 @@ const InputDropDown = ({
104
112
  };
105
113
 
106
114
  return (
107
- <TouchableOpacity onPress={onPress} style={[style, full && styles.wrapper]}>
108
- {renderInputView()}
109
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
110
- </TouchableOpacity>
115
+ <ScreenContext.Provider
116
+ value={{
117
+ ...screenInfo,
118
+ componentName: 'InputOTP',
119
+ params,
120
+ state: 'enabled',
121
+ componentLabel: formatComponentName(floatingValue || ''),
122
+ componentId,
123
+ }}>
124
+ <TouchableOpacity
125
+ onPress={onPress}
126
+ style={[style, full && styles.wrapper]}>
127
+ {renderInputView()}
128
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
129
+ </TouchableOpacity>
130
+ </ScreenContext.Provider>
111
131
  );
112
132
  };
113
133
 
@@ -18,6 +18,11 @@ 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
+
23
+ const {
24
+ ScreenContext,
25
+ } = require('react-native/Libraries/Components/ScreenContext');
21
26
 
22
27
  const InputMoney = forwardRef(
23
28
  (
@@ -36,7 +41,9 @@ const InputMoney = forwardRef(
36
41
  required = false,
37
42
  errorSpacing,
38
43
  style,
44
+ params,
39
45
  defaultValue = '',
46
+ componentId,
40
47
  ...props
41
48
  }: InputMoneyProps,
42
49
  ref,
@@ -44,6 +51,7 @@ const InputMoney = forwardRef(
44
51
  const {theme} = useContext(ApplicationContext);
45
52
  const [focused, setFocused] = useState(false);
46
53
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
54
+ const screenInfo = useContext<any>(ScreenContext);
47
55
 
48
56
  const validateText = (text: string) => {
49
57
  const valueFormat = formatMoneyToNumber(text, 'đ');
@@ -151,11 +159,34 @@ const InputMoney = forwardRef(
151
159
  );
152
160
  };
153
161
 
162
+ let inputState = 'active';
163
+
164
+ if (value && value?.length > 0) {
165
+ inputState = 'filled';
166
+ }
167
+ if (errorMessage && errorMessage?.length > 0) {
168
+ inputState = 'error';
169
+ }
170
+
171
+ if (disabled) {
172
+ inputState = 'disabled';
173
+ }
174
+
154
175
  return (
155
- <View style={[style, styles.wrapper]}>
156
- {renderInputView()}
157
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
158
- </View>
176
+ <ScreenContext.Provider
177
+ value={{
178
+ ...screenInfo,
179
+ componentName: 'InputMoney',
180
+ params,
181
+ componentLabel: formatComponentName(floatingValue || ''),
182
+ state: inputState,
183
+ componentId,
184
+ }}>
185
+ <View style={[style, styles.wrapper]}>
186
+ {renderInputView()}
187
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
188
+ </View>
189
+ </ScreenContext.Provider>
159
190
  );
160
191
  },
161
192
  );
@@ -21,6 +21,11 @@ import styles from './styles';
21
21
  import {ErrorView, getBorderColor} from './common';
22
22
  import {ApplicationContext} from '../Application';
23
23
  import {Spacing} from '../Consts';
24
+ import {formatComponentName} from '../Application/utils';
25
+
26
+ const {
27
+ ScreenContext,
28
+ } = require('react-native/Libraries/Components/ScreenContext');
24
29
 
25
30
  const OTPCaret: FC<CaretProps> = ({index, length}) => {
26
31
  const DURATION = 300;
@@ -78,7 +83,9 @@ const InputOTP = forwardRef(
78
83
  onFocus,
79
84
  onBlur,
80
85
  dataType = 'number',
86
+ params,
81
87
  style,
88
+ componentId,
82
89
  ...props
83
90
  }: InputOTPProps,
84
91
  ref,
@@ -88,6 +95,7 @@ const InputOTP = forwardRef(
88
95
  const [focused, setFocused] = useState(false);
89
96
  const inputRef = useRef<TextInput>(null);
90
97
  const {theme} = useContext(ApplicationContext);
98
+ const screenInfo = useContext<any>(ScreenContext);
91
99
 
92
100
  useImperativeHandle(ref, () => ({
93
101
  onChangeText: (text: string) => {
@@ -221,13 +229,23 @@ const InputOTP = forwardRef(
221
229
  };
222
230
 
223
231
  return (
224
- <TouchableOpacity
225
- activeOpacity={1}
226
- onPress={onFocusInput}
227
- style={[style, styles.otpWrapper]}>
228
- {renderInputView()}
229
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
230
- </TouchableOpacity>
232
+ <ScreenContext.Provider
233
+ value={{
234
+ ...screenInfo,
235
+ componentName: 'InputOTP',
236
+ params,
237
+ componentLabel: formatComponentName(floatingValue || ''),
238
+ state: 'enabled',
239
+ componentId,
240
+ }}>
241
+ <TouchableOpacity
242
+ activeOpacity={1}
243
+ onPress={onFocusInput}
244
+ style={[style, styles.otpWrapper]}>
245
+ {renderInputView()}
246
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
247
+ </TouchableOpacity>
248
+ </ScreenContext.Provider>
231
249
  );
232
250
  },
233
251
  );
@@ -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
  {
@@ -28,7 +32,9 @@ const InputSearch = forwardRef(
28
32
  style,
29
33
  defaultValue,
30
34
  onPressButtonText,
31
- hasColorBG = true,
35
+ hasColorBG = true,
36
+ params,
37
+ componentId,
32
38
  ...props
33
39
  }: InputSearchProps,
34
40
  ref,
@@ -37,6 +43,7 @@ const InputSearch = forwardRef(
37
43
  const [focused, setFocused] = useState(false);
38
44
  const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
39
45
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
46
+ const screenInfo = useContext<any>(ScreenContext);
40
47
 
41
48
  const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
42
49
  setFocused(true);
@@ -117,33 +124,56 @@ const InputSearch = forwardRef(
117
124
  );
118
125
  };
119
126
 
120
- const backgroundColor = hasColorBG ?theme.colors.background.default:theme.colors.background.surface
127
+ let inputState = 'empty';
128
+
129
+ if (focused) {
130
+ inputState = 'focus';
131
+ }
132
+
133
+ if (value && value?.length > 0) {
134
+ inputState = 'filled';
135
+ }
136
+
137
+ const backgroundColor = hasColorBG
138
+ ? theme.colors.background.default
139
+ : theme.colors.background.surface;
140
+
121
141
  return (
122
- <View style={[style, styles.searchInputContainer]}>
123
- <View
124
- style={[
125
- styles.searchInputWrapper,
126
- {
127
- backgroundColor,
128
- borderColor: theme.colors.background.surface,
129
- }
130
- ]}>
131
- <Icon
132
- source={'navigation_search'}
133
- size={24}
134
- color={theme.colors.text.hint}
135
- />
136
- {renderInputView()}
137
- {renderIconView()}
142
+ <ScreenContext.Provider
143
+ value={{
144
+ ...screenInfo,
145
+ componentName: 'InputSearch',
146
+ params,
147
+ state: inputState,
148
+ componentId,
149
+ }}>
150
+ <View style={[style, styles.searchInputContainer]}>
151
+ <View
152
+ style={[
153
+ styles.searchInputWrapper,
154
+ {
155
+ backgroundColor,
156
+ },
157
+ ]}>
158
+ <Icon
159
+ source={'navigation_search'}
160
+ size={24}
161
+ color={theme.colors.text.hint}
162
+ />
163
+ {renderInputView()}
164
+ {renderIconView()}
165
+ </View>
166
+ {showButtonText && (
167
+ <TouchableOpacity onPress={onPressButtonText}>
168
+ <Text
169
+ typography={'action_default_bold'}
170
+ style={styles.textButton}>
171
+ {buttonText}
172
+ </Text>
173
+ </TouchableOpacity>
174
+ )}
138
175
  </View>
139
- {showButtonText && (
140
- <TouchableOpacity onPress={onPressButtonText}>
141
- <Text typography={'action_default_bold'} style={styles.textButton}>
142
- {buttonText}
143
- </Text>
144
- </TouchableOpacity>
145
- )}
146
- </View>
176
+ </ScreenContext.Provider>
147
177
  );
148
178
  },
149
179
  );
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<
@@ -121,7 +124,14 @@ export interface InputSearchProps extends TextInputProps {
121
124
  */
122
125
  icon?: string;
123
126
 
124
- hasColorBG?: boolean
127
+ /**
128
+ *
129
+ */
130
+ hasColorBG?: boolean;
131
+
132
+ params?: any;
133
+
134
+ componentId?: string;
125
135
  }
126
136
 
127
137
  export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
@@ -245,7 +255,22 @@ export interface InputDropDownProps {
245
255
  */
246
256
  leadingIconColor?: string;
247
257
 
248
- style: ViewStyle | ViewStyle[];
258
+ /**
259
+ * Optional. params for element tracking.
260
+ */
261
+ params?: {
262
+ [key: string]: any;
263
+ };
264
+
265
+ /**
266
+ * component id for element tracking.
267
+ */
268
+ componentId?: string;
269
+
270
+ /**
271
+ * Optional. Represents the style of the InputDropDown component.
272
+ */
273
+ style?: ViewStyle | ViewStyle[];
249
274
  }
250
275
 
251
276
  export {Input, InputTextArea, InputSearch, InputMoney, InputOTP, InputDropDown};
package/Input/styles.ts CHANGED
@@ -100,7 +100,6 @@ export default StyleSheet.create({
100
100
  searchInputWrapper: {
101
101
  flexDirection: 'row',
102
102
  borderRadius: Radius.XL,
103
- borderWidth: 1,
104
103
  paddingHorizontal: Spacing.S,
105
104
  alignItems: 'center',
106
105
  flex: 1,
package/Layout/Screen.tsx CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  View,
9
9
  ViewProps,
10
10
  } from 'react-native';
11
- import {useHeaderHeight} from '@react-navigation/elements';
11
+ import {useHeaderHeight} from '@react-navigation/stack';
12
12
  import {useSafeAreaInsets} from 'react-native-safe-area-context';
13
13
  import React, {
14
14
  forwardRef,
package/Layout/index.ts CHANGED
@@ -7,7 +7,6 @@ import {GridContextProps} from './types';
7
7
  import Item from './Item';
8
8
  import ItemList from './ItemList';
9
9
  import ItemSectionList from './ItemSectionList';
10
- import Screen from './Screen';
11
10
 
12
11
  const GridContext = createContext<GridContextProps>({
13
12
  numberOfColumns: 12,
@@ -25,5 +24,4 @@ export {
25
24
  Item,
26
25
  ItemList,
27
26
  ItemSectionList,
28
- Screen,
29
27
  };
@@ -14,7 +14,7 @@ const DotLoader: FC<LoaderProps> = ({color}) => {
14
14
  color ?? theme.colors.primary,
15
15
  ];
16
16
 
17
- let source: any = require('../Assets/DotAnimation.json');
17
+ let source: any = animation;
18
18
  source.assets[0].layers[0].shapes[0].it.forEach((item: any) => {
19
19
  if (item.ty === 'fl' && item.c) {
20
20
  item.c.k.forEach((fillItem: any, index: number) => {
@@ -1,5 +1,6 @@
1
1
  import React, {FC, useContext} from 'react';
2
2
  import AnimatedLottieView from 'lottie-react-native';
3
+ import animation from '../Assets/SpinnerAnimation.json';
3
4
  import {hexToRGBA} from './utils';
4
5
  import {ApplicationContext} from '../Application';
5
6
  import {LoaderProps} from './types';
@@ -7,7 +8,7 @@ import {LoaderProps} from './types';
7
8
  const Spinner: FC<LoaderProps> = ({color}) => {
8
9
  const {theme} = useContext(ApplicationContext);
9
10
 
10
- let source: any = require('../Assets/DotAnimation.json');
11
+ let source: any = animation;
11
12
  source.assets[0].layers.forEach((layer: any) => {
12
13
  layer.shapes[0].it.forEach((item: any) => {
13
14
  if (item.ty === 'fl' && item.c) {
package/Radio/index.tsx CHANGED
@@ -6,6 +6,11 @@ import {Text} from '../Text';
6
6
  import styles from './styles';
7
7
  import {ApplicationContext} from '../Application';
8
8
  import {Spacing} from '../Consts';
9
+ import {formatNameLength} from '../Application/utils';
10
+
11
+ const {
12
+ ScreenContext,
13
+ } = require('react-native/Libraries/Components/ScreenContext');
9
14
 
10
15
  const Radio: FC<RadioProps> = ({
11
16
  value,
@@ -14,8 +19,11 @@ const Radio: FC<RadioProps> = ({
14
19
  onChange,
15
20
  label,
16
21
  style,
22
+ params,
23
+ componentId,
17
24
  }) => {
18
25
  const {theme} = useContext(ApplicationContext);
26
+ const screenInfo = useContext<any>(ScreenContext);
19
27
  const selected = value === groupValue;
20
28
  let disabledStyle = {};
21
29
  let checkBoxStyle = {
@@ -38,26 +46,38 @@ const Radio: FC<RadioProps> = ({
38
46
  }
39
47
 
40
48
  return (
41
- <TouchableOpacity
42
- onPress={onChange}
43
- disabled={disabled}
44
- style={[
45
- style,
46
- {
47
- flexDirection: 'row',
48
- alignItems: 'center',
49
- },
50
- ]}>
51
- <View
49
+ <ScreenContext.Provider
50
+ value={{
51
+ ...screenInfo,
52
+ componentName: 'Button',
53
+ params,
54
+ state: disabled ? 'disabled' : 'enabled',
55
+ componentId,
56
+ componentLabel: formatNameLength(label || ''),
57
+ componentValue: value,
58
+ action: 'click',
59
+ }}>
60
+ <TouchableOpacity
61
+ onPress={onChange}
62
+ disabled={disabled}
52
63
  style={[
53
- styles.radio,
54
- checkBoxStyle,
55
- disabledStyle,
56
- {marginRight: label ? Spacing.XS : 0},
57
- ]}
58
- />
59
- {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
60
- </TouchableOpacity>
64
+ style,
65
+ {
66
+ flexDirection: 'row',
67
+ alignItems: 'center',
68
+ },
69
+ ]}>
70
+ <View
71
+ style={[
72
+ styles.radio,
73
+ checkBoxStyle,
74
+ disabledStyle,
75
+ {marginRight: label ? Spacing.XS : 0},
76
+ ]}
77
+ />
78
+ {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
79
+ </TouchableOpacity>
80
+ </ScreenContext.Provider>
61
81
  );
62
82
  };
63
83
 
package/Radio/types.ts CHANGED
@@ -35,4 +35,9 @@ export type RadioProps = {
35
35
  * Accepts an object of style properties.
36
36
  */
37
37
  style?: ViewStyle;
38
+
39
+
40
+ params?: any
41
+
42
+ componentId?: string
38
43
  };