@momo-kits/foundation 0.81.43-rc.6 → 0.81.43-tracking.10
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.
- package/Application/Components.tsx +27 -17
- package/Application/ModalScreen.tsx +0 -1
- package/Application/NavigationContainer.tsx +0 -2
- package/Application/Navigator.ts +0 -14
- package/Application/StackScreen.tsx +38 -30
- package/Application/index.ts +10 -1
- package/Application/types.ts +10 -9
- package/Badge/Badge.tsx +1 -1
- package/Button/index.tsx +35 -15
- package/IconButton/index.tsx +28 -8
- package/Input/Input.tsx +23 -6
- package/Input/InputMoney.tsx +36 -7
- package/Input/InputOTP.tsx +25 -8
- package/Input/InputSearch.tsx +46 -27
- package/Input/index.tsx +7 -0
- package/Popup/PopupNotify.tsx +26 -29
- package/Popup/PopupPromotion.tsx +23 -27
- package/Text/styles.ts +1 -1
- package/Text/types.ts +1 -1
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
View,
|
|
16
16
|
ViewStyle,
|
|
17
17
|
} from 'react-native';
|
|
18
|
-
import {ApplicationContext} from './index';
|
|
18
|
+
import {ApplicationContext, MiniAppContext} from './index';
|
|
19
19
|
import {Colors, Radius, Spacing, Styles} from '../Consts';
|
|
20
20
|
import {Image} from '../Image';
|
|
21
21
|
import {
|
|
@@ -108,6 +108,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
108
108
|
useBorder,
|
|
109
109
|
accessibilityLabel = '',
|
|
110
110
|
}) => {
|
|
111
|
+
const context = useContext(MiniAppContext);
|
|
111
112
|
const {navigator} = useContext(ApplicationContext);
|
|
112
113
|
|
|
113
114
|
useEffect(() => {
|
|
@@ -122,13 +123,10 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
122
123
|
const goBackSafe = () => {
|
|
123
124
|
const goBack = () => {
|
|
124
125
|
const canGoBack = navigator?.ref.current?.canGoBack();
|
|
125
|
-
if (!canGoBack
|
|
126
|
+
if (!canGoBack) {
|
|
126
127
|
const currentRoute = navigator?.ref?.current.getCurrentRoute();
|
|
127
128
|
navigator?.maxApi?.trackEvent?.('service_icon_clicked', {
|
|
128
|
-
|
|
129
|
-
app_id: navigator.trackingInfo.appId,
|
|
130
|
-
miniapp_version: navigator.trackingInfo.buildNumber,
|
|
131
|
-
flow_partner_id: navigator.trackingInfo.flowPartnerId,
|
|
129
|
+
...context,
|
|
132
130
|
screen_name: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
133
131
|
trigger_id: '111154000000000000',
|
|
134
132
|
icon_name: 'back',
|
|
@@ -244,7 +242,7 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
|
244
242
|
)}
|
|
245
243
|
</View>
|
|
246
244
|
<View style={[Styles.flex, {paddingHorizontal: 8}]}>
|
|
247
|
-
<Text typography="
|
|
245
|
+
<Text typography="header_default_bold" color={tintColor}>
|
|
248
246
|
{title}
|
|
249
247
|
</Text>
|
|
250
248
|
<Text typography="description_default_regular" color={tintColor}>
|
|
@@ -310,15 +308,19 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
310
308
|
}, []);
|
|
311
309
|
|
|
312
310
|
const getToolkitConfig = () => {
|
|
313
|
-
navigator?.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
311
|
+
navigator?.maxApi?.dispatchFunction?.(
|
|
312
|
+
'getToolsConfig',
|
|
313
|
+
[undefined],
|
|
314
|
+
(config: any) => {
|
|
315
|
+
navigator.toolkitConfig = config;
|
|
316
|
+
setToolConfig(navigator?.toolkitConfig);
|
|
317
|
+
},
|
|
318
|
+
);
|
|
317
319
|
};
|
|
318
320
|
|
|
319
321
|
const onMore = () => {
|
|
320
322
|
onAction?.('onMore');
|
|
321
|
-
navigator?.
|
|
323
|
+
navigator?.maxApi?.dispatchFunction?.(
|
|
322
324
|
'showTools',
|
|
323
325
|
[undefined],
|
|
324
326
|
(res: {item: {action?: string; key: string}}) => {
|
|
@@ -339,14 +341,18 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
339
341
|
title: preventBack.primary.title,
|
|
340
342
|
onPress: () => {
|
|
341
343
|
preventBack?.primary.onPress();
|
|
342
|
-
navigator?.
|
|
344
|
+
navigator?.maxApi?.dispatchFunction?.(
|
|
345
|
+
'dismiss',
|
|
346
|
+
undefined,
|
|
347
|
+
undefined,
|
|
348
|
+
);
|
|
343
349
|
},
|
|
344
350
|
}}
|
|
345
351
|
/>
|
|
346
352
|
),
|
|
347
353
|
});
|
|
348
354
|
} else {
|
|
349
|
-
navigator?.
|
|
355
|
+
navigator?.maxApi?.dispatchFunction?.('dismiss', undefined, undefined);
|
|
350
356
|
}
|
|
351
357
|
};
|
|
352
358
|
|
|
@@ -364,9 +370,13 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
364
370
|
badgeValue={badgeValue}
|
|
365
371
|
badgeType={badgeType}
|
|
366
372
|
onPress={() => {
|
|
367
|
-
navigator?.
|
|
368
|
-
|
|
369
|
-
|
|
373
|
+
navigator?.maxApi?.dispatchFunction?.(
|
|
374
|
+
'onToolAction',
|
|
375
|
+
[pinTool?.key],
|
|
376
|
+
() => {
|
|
377
|
+
getToolkitConfig();
|
|
378
|
+
},
|
|
379
|
+
);
|
|
370
380
|
navigator?.toolkitCallback?.(pinTool.key);
|
|
371
381
|
}}
|
|
372
382
|
/>
|
|
@@ -23,7 +23,6 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
23
23
|
options,
|
|
24
24
|
maxApi,
|
|
25
25
|
localization,
|
|
26
|
-
trackingInfo,
|
|
27
26
|
}) => {
|
|
28
27
|
const navigationRef = React.useRef<NavigationContainerRef>(null);
|
|
29
28
|
const navigator = useRef(new Navigator(navigationRef));
|
|
@@ -68,7 +67,6 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
68
67
|
* inject data for navigator
|
|
69
68
|
*/
|
|
70
69
|
navigator.current.maxApi = maxApi;
|
|
71
|
-
navigator.current.trackingInfo = trackingInfo;
|
|
72
70
|
|
|
73
71
|
/**
|
|
74
72
|
* translate
|
package/Application/Navigator.ts
CHANGED
|
@@ -4,14 +4,12 @@ import {
|
|
|
4
4
|
HeaderToolkitProps,
|
|
5
5
|
ModalParams,
|
|
6
6
|
ScreenParams,
|
|
7
|
-
TrackingInfo,
|
|
8
7
|
} from './types';
|
|
9
8
|
|
|
10
9
|
class Navigator {
|
|
11
10
|
ref?: any;
|
|
12
11
|
toolkitConfig?: HeaderToolkitProps;
|
|
13
12
|
maxApi?: any;
|
|
14
|
-
trackingInfo?: TrackingInfo;
|
|
15
13
|
dismissData?: any;
|
|
16
14
|
toolkitCallback?: (item: any) => void;
|
|
17
15
|
|
|
@@ -111,18 +109,6 @@ class Navigator {
|
|
|
111
109
|
);
|
|
112
110
|
};
|
|
113
111
|
|
|
114
|
-
/**
|
|
115
|
-
* request max api for mini app
|
|
116
|
-
* @param func
|
|
117
|
-
* @param args
|
|
118
|
-
* @param callback
|
|
119
|
-
*/
|
|
120
|
-
requestApi = (func: any, args: any = [], callback: any) => {
|
|
121
|
-
if (this.maxApi) {
|
|
122
|
-
this.maxApi[func]?.(...args, callback);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
112
|
setToolkitCallback = (
|
|
127
113
|
callback: (item: {key: string; action: string}) => void,
|
|
128
114
|
) => {
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useLayoutEffect} from 'react';
|
|
2
2
|
import {ScreenParams} from './types';
|
|
3
3
|
import Navigation from './Navigation';
|
|
4
|
-
import {ApplicationContext} from './index';
|
|
4
|
+
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
|
-
const {screen: Component, options}: ScreenParams = props.route.params;
|
|
10
13
|
const {theme, showGrid, navigator} = useContext(ApplicationContext);
|
|
14
|
+
const context = useContext(MiniAppContext);
|
|
15
|
+
|
|
16
|
+
const {screen: Component, options}: ScreenParams = props.route.params;
|
|
11
17
|
const navigation = new Navigation(props.navigation, theme);
|
|
12
18
|
const heightHeader = useHeaderHeight();
|
|
13
19
|
|
|
@@ -31,43 +37,45 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
31
37
|
* tracking for screen
|
|
32
38
|
*/
|
|
33
39
|
useEffect(() => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
miniapp_version: navigator.trackingInfo.buildNumber,
|
|
39
|
-
flow_partner_id: navigator.trackingInfo.flowPartnerId,
|
|
40
|
-
screen_name: Component.name,
|
|
41
|
-
};
|
|
40
|
+
const tracking = {
|
|
41
|
+
...context,
|
|
42
|
+
screen_name: Component.name,
|
|
43
|
+
};
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
const routes = props.navigation.getState()?.routes || [];
|
|
46
|
+
const routesLength = routes.length;
|
|
47
|
+
let pre_screen_name = '';
|
|
48
|
+
if (routesLength > 1) {
|
|
49
|
+
pre_screen_name = routes[routesLength - 2]?.params?.screen?.name;
|
|
50
|
+
}
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
navigator?.maxApi?.trackEvent?.('service_frame_displayed', {
|
|
53
|
+
...tracking,
|
|
54
|
+
pre_screen_name,
|
|
55
|
+
trigger_id: '111378000000000000',
|
|
56
|
+
});
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
});
|
|
58
|
+
return props.navigation.addListener('beforeRemove', () => {
|
|
59
|
+
navigator?.maxApi?.trackEvent?.('service_icon_clicked', {
|
|
60
|
+
...tracking,
|
|
61
|
+
trigger_id: '111154000000000000',
|
|
62
|
+
icon_name: 'back',
|
|
62
63
|
});
|
|
63
|
-
}
|
|
64
|
+
});
|
|
64
65
|
}, []);
|
|
65
66
|
|
|
66
67
|
return (
|
|
67
|
-
|
|
68
|
+
<ScreenContext.Provider
|
|
69
|
+
value={{
|
|
70
|
+
...context,
|
|
71
|
+
screenName: Component.name,
|
|
72
|
+
autoTracking: (data: any) => {
|
|
73
|
+
navigator?.maxApi?.dispatchFunction?.('autoTracking', data);
|
|
74
|
+
},
|
|
75
|
+
}}>
|
|
68
76
|
<Component heightHeader={heightHeader} {...params} />
|
|
69
77
|
{showGrid && <GridSystem />}
|
|
70
|
-
|
|
78
|
+
</ScreenContext.Provider>
|
|
71
79
|
);
|
|
72
80
|
};
|
|
73
81
|
|
package/Application/index.ts
CHANGED
|
@@ -13,12 +13,21 @@ import {
|
|
|
13
13
|
import BottomTab from './BottomTab';
|
|
14
14
|
import {createContext} from 'react';
|
|
15
15
|
import {defaultContext} from '../Consts';
|
|
16
|
+
import {MiniAppInfo} from './types';
|
|
16
17
|
|
|
17
18
|
const ApplicationContext = createContext(defaultContext);
|
|
19
|
+
const MiniAppContext = createContext<MiniAppInfo>({
|
|
20
|
+
appId: '',
|
|
21
|
+
buildNumber: 0,
|
|
22
|
+
code: '',
|
|
23
|
+
toolkitConfig: {},
|
|
24
|
+
fromCode: '',
|
|
25
|
+
});
|
|
18
26
|
|
|
19
27
|
export {
|
|
20
|
-
NavigationContainer,
|
|
21
28
|
ApplicationContext,
|
|
29
|
+
MiniAppContext,
|
|
30
|
+
NavigationContainer,
|
|
22
31
|
Screen,
|
|
23
32
|
BottomTab,
|
|
24
33
|
NavigationButton,
|
package/Application/types.ts
CHANGED
|
@@ -71,6 +71,16 @@ export type Context = {
|
|
|
71
71
|
translate?: (key: string) => string;
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
+
export type MiniAppInfo = {
|
|
75
|
+
[key: string]: any;
|
|
76
|
+
code: string;
|
|
77
|
+
appId: string;
|
|
78
|
+
buildNumber: number;
|
|
79
|
+
flowPartnerId?: string;
|
|
80
|
+
toolkitConfig?: object;
|
|
81
|
+
fromCode?: string;
|
|
82
|
+
};
|
|
83
|
+
|
|
74
84
|
export type LocalizationObject = {
|
|
75
85
|
vi: {
|
|
76
86
|
[key: string]: string;
|
|
@@ -80,21 +90,12 @@ export type LocalizationObject = {
|
|
|
80
90
|
};
|
|
81
91
|
};
|
|
82
92
|
|
|
83
|
-
export type TrackingInfo = {
|
|
84
|
-
[key: string]: any;
|
|
85
|
-
code: string;
|
|
86
|
-
appId: string;
|
|
87
|
-
buildNumber: number;
|
|
88
|
-
flowPartnerId?: string;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
93
|
export type NavigationContainerProps = {
|
|
92
94
|
screen: Screen;
|
|
93
95
|
options?: NavigationOptions;
|
|
94
96
|
theme: Theme;
|
|
95
97
|
maxApi: any;
|
|
96
98
|
localization?: LocalizationObject;
|
|
97
|
-
trackingInfo?: TrackingInfo;
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
export type NavigationScreenProps = {
|
package/Badge/Badge.tsx
CHANGED
|
@@ -46,7 +46,7 @@ const Badge: FC<BadgeProps> = ({label = 'Label', style, backgroundColor}) => {
|
|
|
46
46
|
|
|
47
47
|
return (
|
|
48
48
|
<View style={[style, styles.badge, {backgroundColor: badgeColor}]}>
|
|
49
|
-
<Text color={Colors.black_01} typography={'
|
|
49
|
+
<Text color={Colors.black_01} typography={'action_xs_bold'}>
|
|
50
50
|
{formatTitle()}
|
|
51
51
|
</Text>
|
|
52
52
|
</View>
|
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
|
-
<
|
|
295
|
-
{
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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
|
|
package/IconButton/index.tsx
CHANGED
|
@@ -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
|
-
<
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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,22 @@ const Input = forwardRef(
|
|
|
160
167
|
};
|
|
161
168
|
|
|
162
169
|
return (
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
170
|
+
<ScreenContext.Provider
|
|
171
|
+
value={{
|
|
172
|
+
...screenInfo,
|
|
173
|
+
componentName: 'Input',
|
|
174
|
+
params,
|
|
175
|
+
state: disabled ? 'disabled' : 'enabled',
|
|
176
|
+
componentId,
|
|
177
|
+
action: 'focus',
|
|
178
|
+
}}>
|
|
179
|
+
<View
|
|
180
|
+
style={[style, styles.wrapper]}
|
|
181
|
+
accessibilityLabel={accessibilityLabel}>
|
|
182
|
+
{renderInputView()}
|
|
183
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
184
|
+
</View>
|
|
185
|
+
</ScreenContext.Provider>
|
|
169
186
|
);
|
|
170
187
|
},
|
|
171
188
|
);
|
package/Input/InputMoney.tsx
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useContext,
|
|
4
|
+
useImperativeHandle,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
NativeSyntheticEvent,
|
|
4
10
|
TextInput,
|
|
@@ -13,6 +19,10 @@ import {InputMoneyProps} from './index';
|
|
|
13
19
|
import {Icon} from '../Icon';
|
|
14
20
|
import {formatMoneyToNumber, formatNumberToMoney} from './utils';
|
|
15
21
|
|
|
22
|
+
const {
|
|
23
|
+
ScreenContext,
|
|
24
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
25
|
+
|
|
16
26
|
const InputMoney = forwardRef(
|
|
17
27
|
(
|
|
18
28
|
{
|
|
@@ -30,7 +40,9 @@ const InputMoney = forwardRef(
|
|
|
30
40
|
required = false,
|
|
31
41
|
errorSpacing,
|
|
32
42
|
style,
|
|
43
|
+
params,
|
|
33
44
|
defaultValue = '',
|
|
45
|
+
componentId,
|
|
34
46
|
...props
|
|
35
47
|
}: InputMoneyProps,
|
|
36
48
|
ref,
|
|
@@ -39,6 +51,7 @@ const InputMoney = forwardRef(
|
|
|
39
51
|
const [focused, setFocused] = useState(false);
|
|
40
52
|
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
41
53
|
const accessibilityLabel = `InputMoney/${floatingValue}`;
|
|
54
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
42
55
|
|
|
43
56
|
const validateText = (text: string) => {
|
|
44
57
|
const valueFormat = formatMoneyToNumber(text, 'đ');
|
|
@@ -63,6 +76,12 @@ const InputMoney = forwardRef(
|
|
|
63
76
|
onChangeText?.(formatMoneyToNumber(text, 'đ').toString());
|
|
64
77
|
};
|
|
65
78
|
|
|
79
|
+
useImperativeHandle(ref, () => {
|
|
80
|
+
return {
|
|
81
|
+
setText: _onChangeText,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
|
|
66
85
|
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
67
86
|
setFocused(true);
|
|
68
87
|
onFocus?.(e);
|
|
@@ -142,12 +161,22 @@ const InputMoney = forwardRef(
|
|
|
142
161
|
};
|
|
143
162
|
|
|
144
163
|
return (
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
164
|
+
<ScreenContext.Provider
|
|
165
|
+
value={{
|
|
166
|
+
...screenInfo,
|
|
167
|
+
componentName: 'InputMoney',
|
|
168
|
+
params,
|
|
169
|
+
state: 'enable',
|
|
170
|
+
componentId,
|
|
171
|
+
action: 'focus',
|
|
172
|
+
}}>
|
|
173
|
+
<View
|
|
174
|
+
style={[style, styles.wrapper]}
|
|
175
|
+
accessibilityLabel={accessibilityLabel}>
|
|
176
|
+
{renderInputView()}
|
|
177
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
178
|
+
</View>
|
|
179
|
+
</ScreenContext.Provider>
|
|
151
180
|
);
|
|
152
181
|
},
|
|
153
182
|
);
|
package/Input/InputOTP.tsx
CHANGED
|
@@ -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,24 @@ const InputOTP = forwardRef(
|
|
|
223
230
|
};
|
|
224
231
|
|
|
225
232
|
return (
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
233
|
+
<ScreenContext.Provider
|
|
234
|
+
value={{
|
|
235
|
+
...screenInfo,
|
|
236
|
+
componentName: 'InputOTP',
|
|
237
|
+
params,
|
|
238
|
+
state: 'enable',
|
|
239
|
+
componentId,
|
|
240
|
+
action: 'focus',
|
|
241
|
+
}}>
|
|
242
|
+
<TouchableOpacity
|
|
243
|
+
activeOpacity={1}
|
|
244
|
+
onPress={onFocusInput}
|
|
245
|
+
style={[style, styles.otpWrapper]}
|
|
246
|
+
accessibilityLabel={accessibilityLabel}>
|
|
247
|
+
{renderInputView()}
|
|
248
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
249
|
+
</TouchableOpacity>
|
|
250
|
+
</ScreenContext.Provider>
|
|
234
251
|
);
|
|
235
252
|
},
|
|
236
253
|
);
|
package/Input/InputSearch.tsx
CHANGED
|
@@ -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,47 @@ const InputSearch = forwardRef(
|
|
|
119
126
|
);
|
|
120
127
|
};
|
|
121
128
|
return (
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
129
|
+
<ScreenContext.Provider
|
|
130
|
+
value={{
|
|
131
|
+
...screenInfo,
|
|
132
|
+
componentName: 'InputSearch',
|
|
133
|
+
params,
|
|
134
|
+
state: 'enabled',
|
|
135
|
+
componentId,
|
|
136
|
+
action: 'focus',
|
|
137
|
+
}}>
|
|
125
138
|
<View
|
|
126
|
-
style={[
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
style={[style, styles.searchInputContainer]}
|
|
140
|
+
accessibilityLabel={accessibilityLabel}>
|
|
141
|
+
<View
|
|
142
|
+
style={[
|
|
143
|
+
styles.searchInputWrapper,
|
|
144
|
+
{
|
|
145
|
+
backgroundColor: theme.colors.background.surface,
|
|
146
|
+
borderColor: theme.colors.background.surface,
|
|
147
|
+
},
|
|
148
|
+
showBorder && {borderColor: theme.colors.border.default},
|
|
149
|
+
focused && {borderColor: theme.colors.primary},
|
|
150
|
+
]}>
|
|
151
|
+
<Icon
|
|
152
|
+
source={'navigation_search'}
|
|
153
|
+
size={24}
|
|
154
|
+
color={theme.colors.text.hint}
|
|
155
|
+
/>
|
|
156
|
+
{renderInputView()}
|
|
157
|
+
{renderIconView()}
|
|
158
|
+
</View>
|
|
159
|
+
{showButtonText && (
|
|
160
|
+
<TouchableOpacity onPress={onPressButtonText}>
|
|
161
|
+
<Text
|
|
162
|
+
typography={'action_default_bold'}
|
|
163
|
+
style={styles.textButton}>
|
|
164
|
+
{buttonText}
|
|
165
|
+
</Text>
|
|
166
|
+
</TouchableOpacity>
|
|
167
|
+
)}
|
|
142
168
|
</View>
|
|
143
|
-
|
|
144
|
-
<TouchableOpacity onPress={onPressButtonText}>
|
|
145
|
-
<Text typography={'action_default_bold'} style={styles.textButton}>
|
|
146
|
-
{buttonText}
|
|
147
|
-
</Text>
|
|
148
|
-
</TouchableOpacity>
|
|
149
|
-
)}
|
|
150
|
-
</View>
|
|
169
|
+
</ScreenContext.Provider>
|
|
151
170
|
);
|
|
152
171
|
},
|
|
153
172
|
);
|
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/Popup/PopupNotify.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import {PopupNotifyProps} from './types';
|
|
|
4
4
|
import {Radius, Spacing, Styles} from '../Consts';
|
|
5
5
|
import {Image} from '../Image';
|
|
6
6
|
import {Text} from '../Text';
|
|
7
|
-
import {ApplicationContext} from '../Application';
|
|
7
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
8
8
|
import {Button} from '../Button';
|
|
9
9
|
import {Icon} from '../Icon';
|
|
10
10
|
|
|
@@ -19,6 +19,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
19
19
|
buttonDirection = 'row',
|
|
20
20
|
onIconClose,
|
|
21
21
|
}) => {
|
|
22
|
+
const context = useContext(MiniAppContext);
|
|
22
23
|
const {theme, navigator, translate} = useContext(ApplicationContext);
|
|
23
24
|
const [scrollContent, setScrollContent] = useState(false);
|
|
24
25
|
const closeAction = useRef('touch_outside');
|
|
@@ -34,35 +35,31 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
34
35
|
* tracking
|
|
35
36
|
*/
|
|
36
37
|
useEffect(() => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
38
|
+
const routes = navigator?.ref.current?.getRootState()?.routes || [];
|
|
39
|
+
const routesLength = routes.length;
|
|
40
|
+
let screen_name = routes?.[0]?.params?.screen?.name;
|
|
41
|
+
if (routesLength > 1) {
|
|
42
|
+
screen_name = routes[routesLength - 2]?.params?.screen?.name;
|
|
43
|
+
}
|
|
44
|
+
const tracking = {
|
|
45
|
+
...context,
|
|
46
|
+
screen_name,
|
|
47
|
+
component_type: 'popup',
|
|
48
|
+
component_name: id,
|
|
49
|
+
error_code: error ? error : undefined,
|
|
50
|
+
};
|
|
51
|
+
navigator?.maxApi?.trackEvent?.('service_component_displayed', {
|
|
52
|
+
...tracking,
|
|
53
|
+
trigger_id: '111012100000000000',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return () => {
|
|
57
|
+
navigator?.maxApi?.trackEvent?.('service_popup_dismissed', {
|
|
55
58
|
...tracking,
|
|
56
|
-
trigger_id: '
|
|
59
|
+
trigger_id: '111154100000000001',
|
|
60
|
+
action_type: closeAction.current,
|
|
57
61
|
});
|
|
58
|
-
|
|
59
|
-
navigator?.maxApi?.trackEvent?.('service_popup_dismissed', {
|
|
60
|
-
...tracking,
|
|
61
|
-
trigger_id: '111154100000000001',
|
|
62
|
-
action_type: closeAction.current,
|
|
63
|
-
});
|
|
64
|
-
};
|
|
65
|
-
}
|
|
62
|
+
};
|
|
66
63
|
}, []);
|
|
67
64
|
|
|
68
65
|
/**
|
|
@@ -192,7 +189,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
192
189
|
]}>
|
|
193
190
|
{!!image && <Image source={{uri: image}} style={styles.image} />}
|
|
194
191
|
<View style={styles.content}>
|
|
195
|
-
<Text typography={'
|
|
192
|
+
<Text typography={'header_default_bold'} numberOfLines={1}>
|
|
196
193
|
{title}
|
|
197
194
|
</Text>
|
|
198
195
|
<Description style={[styles.description, descriptionStyle]}>
|
package/Popup/PopupPromotion.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useRef} from 'react';
|
|
2
2
|
import {StyleSheet, TouchableOpacity, View} from 'react-native';
|
|
3
3
|
import {PopupPromotionProps} from './types';
|
|
4
|
-
import {ApplicationContext} from '../Application';
|
|
4
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
5
5
|
import {Image} from '../Image';
|
|
6
6
|
import {Radius, Spacing} from '../Consts';
|
|
7
7
|
import {Icon} from '../Icon';
|
|
@@ -11,6 +11,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
11
11
|
image,
|
|
12
12
|
onIconClose,
|
|
13
13
|
}) => {
|
|
14
|
+
const context = useContext(MiniAppContext);
|
|
14
15
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
15
16
|
const closeAction = useRef('touch_outside');
|
|
16
17
|
|
|
@@ -18,34 +19,29 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
18
19
|
* tracking
|
|
19
20
|
*/
|
|
20
21
|
useEffect(() => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
const routes = navigator?.ref.current?.getRootState()?.routes || [];
|
|
23
|
+
const routesLength = routes.length;
|
|
24
|
+
let screen_name = routes?.[0]?.params?.screen?.name;
|
|
25
|
+
if (routesLength > 1) {
|
|
26
|
+
screen_name = routes[routesLength - 2]?.params?.screen?.name;
|
|
27
|
+
}
|
|
28
|
+
const tracking = {
|
|
29
|
+
...context,
|
|
30
|
+
screen_name,
|
|
31
|
+
component_type: 'popup',
|
|
32
|
+
component_name: id,
|
|
33
|
+
};
|
|
34
|
+
navigator?.maxApi?.trackEvent?.('service_component_displayed', {
|
|
35
|
+
...tracking,
|
|
36
|
+
trigger_id: '111012100000000000',
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
navigator?.maxApi?.trackEvent?.('service_popup_dismissed', {
|
|
38
40
|
...tracking,
|
|
39
|
-
trigger_id: '
|
|
41
|
+
trigger_id: '111154100000000001',
|
|
42
|
+
action_type: closeAction.current,
|
|
40
43
|
});
|
|
41
|
-
|
|
42
|
-
navigator?.maxApi?.trackEvent?.('service_popup_dismissed', {
|
|
43
|
-
...tracking,
|
|
44
|
-
trigger_id: '111154100000000001',
|
|
45
|
-
action_type: closeAction.current,
|
|
46
|
-
});
|
|
47
|
-
};
|
|
48
|
-
}
|
|
44
|
+
};
|
|
49
45
|
}, []);
|
|
50
46
|
|
|
51
47
|
/**
|
package/Text/styles.ts
CHANGED
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
header_s_semibold: {fontSize: 14, lineHeight: 20, fontWeight: '600'},
|
|
6
6
|
header_xs_semibold: {fontSize: 12, lineHeight: 16, fontWeight: '600'},
|
|
7
7
|
body_default_regular: {fontSize: 14, lineHeight: 20, fontWeight: '400'},
|
|
8
|
-
|
|
8
|
+
body_regularstrikethrought: {
|
|
9
9
|
fontSize: 14,
|
|
10
10
|
lineHeight: 20,
|
|
11
11
|
fontWeight: '400',
|
package/Text/types.ts
CHANGED
|
@@ -20,7 +20,7 @@ export type Typography =
|
|
|
20
20
|
| 'header_s_semibold'
|
|
21
21
|
| 'header_xs_semibold'
|
|
22
22
|
| 'body_default_regular'
|
|
23
|
-
| '
|
|
23
|
+
| 'body_regularstrikethrought'
|
|
24
24
|
| 'description_default_regular'
|
|
25
25
|
| 'description_default_regularstrikethrought'
|
|
26
26
|
| 'description_xs_regular'
|