@momo-kits/foundation 0.92.7-rc.21 → 0.92.7-rc.22
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/BottomSheet.tsx +216 -0
- package/Application/BottomTab/BottomTabBar.tsx +62 -223
- package/Application/BottomTab/index.tsx +15 -11
- package/Application/Components.tsx +291 -45
- package/Application/Localize.ts +44 -0
- package/Application/ModalScreen.tsx +11 -181
- package/Application/Navigation.ts +4 -18
- package/Application/NavigationContainer.tsx +10 -28
- package/Application/Navigator.ts +14 -16
- package/Application/StackScreen.tsx +222 -42
- package/Application/index.ts +5 -3
- package/Application/types.ts +47 -29
- package/Application/utils.tsx +61 -19
- package/Assets/icon_bank.json +1 -1
- package/Badge/BadgeDotAnimation.tsx +95 -0
- package/Badge/index.tsx +2 -1
- package/Badge/styles.ts +50 -6
- package/Button/index.tsx +7 -8
- package/Icon/index.tsx +1 -1
- package/Icon/types.ts +1 -2
- package/Image/index.tsx +0 -1
- package/Input/Input.tsx +51 -17
- package/Input/InputDropDown.tsx +42 -45
- package/Input/InputMoney.tsx +65 -6
- package/Input/InputOTP.tsx +14 -13
- package/Input/InputSearch.tsx +259 -146
- package/Input/InputTextArea.tsx +0 -1
- package/Input/TextTyping.tsx +113 -0
- package/Input/common.tsx +29 -10
- package/Input/index.tsx +84 -89
- package/Input/styles.ts +44 -7
- package/Input/utils.ts +1 -1
- package/Layout/Card.tsx +4 -3
- package/Layout/FloatingButton.tsx +3 -3
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/ItemList.tsx +3 -2
- package/Layout/Screen.tsx +188 -102
- package/Layout/Section.tsx +4 -3
- package/Layout/styles.ts +0 -6
- package/Layout/types.ts +1 -1
- package/Layout/utils.ts +2 -2
- package/Loader/index.tsx +2 -0
- package/Pagination/PaginationScroll.tsx +2 -2
- package/Pagination/styles.ts +1 -1
- package/Popup/PopupNotify.tsx +7 -7
- package/Popup/PopupPromotion.tsx +1 -1
- package/Popup/types.ts +1 -1
- package/Tag/index.tsx +9 -2
- package/Tag/styles.ts +3 -2
- package/Tag/types.ts +12 -0
- package/Title/index.tsx +20 -7
- package/Title/styles.ts +4 -4
- package/code-scanner.js +141 -124
- package/index.ts +7 -0
- package/package.json +5 -4
- package/publish.sh +16 -21
- package/tsconfig.json +1 -1
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useLayoutEffect, useRef} from 'react';
|
|
2
|
+
import {useHeaderHeight} from '@react-navigation/stack';
|
|
3
|
+
import {Alert, InteractionManager, Linking, View} from 'react-native';
|
|
2
4
|
import {ScreenParams} from './types';
|
|
3
5
|
import Navigation from './Navigation';
|
|
4
6
|
import {ApplicationContext, MiniAppContext, ScreenContext} from './index';
|
|
5
7
|
import {GridSystem} from '../Layout';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
+
import {Text} from '../Text';
|
|
9
|
+
import {Colors, Radius, Spacing} from '../Consts';
|
|
8
10
|
|
|
11
|
+
/**
|
|
12
|
+
* container for stack screen
|
|
13
|
+
* @param props
|
|
14
|
+
* @constructor
|
|
15
|
+
*/
|
|
9
16
|
const StackScreen: React.FC<ScreenParams> = props => {
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
const endTime = useRef(Date.now());
|
|
13
|
-
const timeLoad = useRef(0);
|
|
14
|
-
const timeInteraction = useRef(0);
|
|
15
|
-
const timeoutLoad = useRef<any>();
|
|
16
|
-
const tracked = useRef<any>({
|
|
17
|
-
releaseLoad: undefined,
|
|
18
|
-
releaseInteraction: undefined,
|
|
17
|
+
const {showGrid, navigator} = useContext(ApplicationContext);
|
|
18
|
+
const tracking = useRef<any>({
|
|
19
19
|
timeoutLoad: undefined,
|
|
20
20
|
timeoutInteraction: undefined,
|
|
21
|
+
timeoutTracking: undefined,
|
|
22
|
+
startTime: Date.now(),
|
|
23
|
+
endTime: Date.now(),
|
|
24
|
+
traceIdLoad: undefined,
|
|
25
|
+
traceIdInteraction: undefined,
|
|
26
|
+
releaseLoad: undefined,
|
|
27
|
+
releaseInteraction: undefined,
|
|
28
|
+
timeLoad: 0,
|
|
29
|
+
timeInteraction: 0,
|
|
21
30
|
});
|
|
22
|
-
const interaction = useRef<any>();
|
|
23
|
-
const context = useContext<any>(MiniAppContext);
|
|
24
31
|
|
|
32
|
+
const context = useContext<any>(MiniAppContext);
|
|
25
33
|
const {screen: Component, options, initialParams} = props.route.params;
|
|
26
|
-
const navigation = new Navigation(props.navigation
|
|
34
|
+
const navigation = new Navigation(props.navigation);
|
|
27
35
|
const heightHeader = useHeaderHeight();
|
|
28
36
|
|
|
29
37
|
const data = {
|
|
@@ -36,36 +44,68 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
36
44
|
delete data.initialParams;
|
|
37
45
|
|
|
38
46
|
const screenName = Component?.name || Component?.type?.name || 'Invalid';
|
|
47
|
+
const routes = props.navigation.getState()?.routes || [];
|
|
39
48
|
|
|
40
49
|
/**
|
|
41
50
|
* set options for screen
|
|
42
51
|
*/
|
|
43
52
|
useLayoutEffect(() => {
|
|
53
|
+
let defaultOptions = {
|
|
54
|
+
headerRight: {
|
|
55
|
+
type: 'toolkit',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
44
58
|
if (options) {
|
|
45
|
-
|
|
59
|
+
defaultOptions = {
|
|
60
|
+
...defaultOptions,
|
|
61
|
+
...options,
|
|
62
|
+
};
|
|
46
63
|
}
|
|
64
|
+
navigation.setOptions(defaultOptions);
|
|
47
65
|
}, [options]);
|
|
48
66
|
|
|
49
67
|
/**
|
|
50
68
|
* tracking for screen
|
|
51
69
|
*/
|
|
52
70
|
useEffect(() => {
|
|
53
|
-
if (
|
|
54
|
-
|
|
71
|
+
if (['Invalid', 'screen'].includes(screenName) && context.enableAutoId) {
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
navigator?.showModal({screen: EmptyScreen});
|
|
74
|
+
}, 300);
|
|
55
75
|
}
|
|
56
76
|
|
|
57
|
-
|
|
77
|
+
const subscription = props.navigation?.addListener?.('focus', () => {
|
|
78
|
+
navigator?.maxApi?.of?.({screenName});
|
|
79
|
+
navigator?.maxApi?.getDataObserver('CURRENT_SCREEN', (data: any) => {
|
|
80
|
+
let preScreenName = data?.screenName;
|
|
81
|
+
if (routes?.length > 1) {
|
|
82
|
+
const screen = routes?.[routes?.length - 2]?.params?.screen;
|
|
83
|
+
preScreenName = screen?.name || screen?.type?.name || 'Invalid';
|
|
84
|
+
}
|
|
85
|
+
onScreenNavigated(preScreenName);
|
|
86
|
+
navigator?.maxApi?.setObserver('CURRENT_SCREEN', {screenName});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
navigator?.maxApi?.startTraceScreenLoad?.(screenName, (data: any) => {
|
|
90
|
+
tracking.current.traceIdLoad = data?.traceId;
|
|
91
|
+
});
|
|
92
|
+
navigator?.maxApi?.startTraceScreenInteraction?.(
|
|
93
|
+
screenName,
|
|
94
|
+
(data: any) => {
|
|
95
|
+
tracking.current.traceIdInteraction = data?.traceId;
|
|
96
|
+
}
|
|
97
|
+
);
|
|
58
98
|
|
|
59
|
-
|
|
99
|
+
tracking.current.timeoutTracking = setTimeout(() => {
|
|
60
100
|
onScreenLoad();
|
|
61
|
-
}, 5000);
|
|
62
|
-
tracked.current.timeoutInteraction = setTimeout(() => {
|
|
63
101
|
onScreenInteraction();
|
|
64
102
|
}, 5000);
|
|
65
103
|
|
|
66
104
|
return () => {
|
|
67
105
|
onScreenLoad();
|
|
68
106
|
onScreenInteraction();
|
|
107
|
+
clearTimeout(tracking.current.timeoutTracking);
|
|
108
|
+
subscription?.();
|
|
69
109
|
};
|
|
70
110
|
}, []);
|
|
71
111
|
|
|
@@ -73,8 +113,12 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
73
113
|
* tracking for screen load
|
|
74
114
|
*/
|
|
75
115
|
const onScreenLoad = () => {
|
|
76
|
-
|
|
77
|
-
|
|
116
|
+
if (!tracking.current?.releaseLoad) {
|
|
117
|
+
if (tracking.current.timeLoad === 0) {
|
|
118
|
+
tracking.current.timeLoad =
|
|
119
|
+
tracking.current.endTime - tracking.current.startTime;
|
|
120
|
+
}
|
|
121
|
+
|
|
78
122
|
context.autoTracking?.({
|
|
79
123
|
appId: context.appId,
|
|
80
124
|
code: context.code,
|
|
@@ -82,13 +126,26 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
82
126
|
screenName,
|
|
83
127
|
componentName: 'Screen',
|
|
84
128
|
state: 'load',
|
|
85
|
-
duration:
|
|
129
|
+
duration: tracking.current.timeLoad,
|
|
86
130
|
});
|
|
131
|
+
navigator?.maxApi?.stopTrace?.(
|
|
132
|
+
tracking.current.traceIdLoad,
|
|
133
|
+
{value: tracking.current.timeLoad / 1000},
|
|
134
|
+
null
|
|
135
|
+
);
|
|
136
|
+
tracking.current.releaseLoad = true;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* debug
|
|
140
|
+
*/
|
|
87
141
|
navigator?.maxApi?.showToastDebug?.({
|
|
88
|
-
appId:
|
|
89
|
-
message: `${screenName} screen_load_time ${
|
|
142
|
+
appId: context.appId,
|
|
143
|
+
message: `${screenName} screen_load_time ${tracking.current.timeLoad}`,
|
|
144
|
+
type: 'ERROR',
|
|
90
145
|
});
|
|
91
|
-
|
|
146
|
+
if (tracking.current.timeLoad <= 0 && context.enableAutoId) {
|
|
147
|
+
Alert.alert(screenName, "Can't get screen load time");
|
|
148
|
+
}
|
|
92
149
|
}
|
|
93
150
|
};
|
|
94
151
|
|
|
@@ -96,8 +153,15 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
96
153
|
* tracking for screen load
|
|
97
154
|
*/
|
|
98
155
|
const onScreenInteraction = () => {
|
|
99
|
-
|
|
100
|
-
|
|
156
|
+
if (!tracking.current?.releaseInteraction) {
|
|
157
|
+
if (tracking.current.timeLoad === 0) {
|
|
158
|
+
tracking.current.timeLoad =
|
|
159
|
+
tracking.current.endTime - tracking.current.startTime;
|
|
160
|
+
}
|
|
161
|
+
if (tracking.current.timeInteraction === 0) {
|
|
162
|
+
tracking.current.timeInteraction = tracking.current.timeLoad;
|
|
163
|
+
}
|
|
164
|
+
|
|
101
165
|
context.autoTracking?.({
|
|
102
166
|
appId: context.appId,
|
|
103
167
|
code: context.code,
|
|
@@ -105,32 +169,74 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
105
169
|
screenName,
|
|
106
170
|
componentName: 'Screen',
|
|
107
171
|
state: 'interaction',
|
|
108
|
-
duration:
|
|
172
|
+
duration: tracking.current.timeInteraction - tracking.current.timeLoad,
|
|
173
|
+
totalDuration: tracking.current.timeInteraction,
|
|
109
174
|
});
|
|
175
|
+
navigator?.maxApi?.stopTrace?.(
|
|
176
|
+
tracking.current.traceIdInteraction,
|
|
177
|
+
{value: tracking.current.timeInteraction / 1000},
|
|
178
|
+
null
|
|
179
|
+
);
|
|
180
|
+
tracking.current.releaseInteraction = true;
|
|
110
181
|
|
|
182
|
+
/**
|
|
183
|
+
* debug toast
|
|
184
|
+
*/
|
|
111
185
|
navigator?.maxApi?.showToastDebug?.({
|
|
112
|
-
appId:
|
|
113
|
-
message: `${screenName} screen_interaction_time ${
|
|
186
|
+
appId: context.appId,
|
|
187
|
+
message: `${screenName} screen_interaction_time ${tracking.current.timeInteraction}`,
|
|
188
|
+
type: 'ERROR',
|
|
114
189
|
});
|
|
115
|
-
|
|
190
|
+
if (tracking.current.timeInteraction <= 0 && context.enableAutoId) {
|
|
191
|
+
Alert.alert(screenName, "Can't get screen interaction time");
|
|
192
|
+
}
|
|
116
193
|
}
|
|
117
194
|
};
|
|
118
195
|
|
|
196
|
+
/**
|
|
197
|
+
* tracking for screen navigated
|
|
198
|
+
*/
|
|
199
|
+
const onScreenNavigated = (preScreenName: string) => {
|
|
200
|
+
context.autoTracking?.({
|
|
201
|
+
appId: context.appId,
|
|
202
|
+
code: context.code,
|
|
203
|
+
buildNumber: context.buildNumber,
|
|
204
|
+
preScreenName,
|
|
205
|
+
screenName,
|
|
206
|
+
componentName: 'Screen',
|
|
207
|
+
state: 'navigated',
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* debug toast
|
|
212
|
+
*/
|
|
213
|
+
navigator?.maxApi?.showToastDebug?.({
|
|
214
|
+
appId: context.appId,
|
|
215
|
+
message: `${screenName} screen_navigated`,
|
|
216
|
+
type: 'ERROR',
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
|
|
119
220
|
return (
|
|
120
221
|
<ScreenContext.Provider
|
|
121
222
|
value={{
|
|
122
223
|
screenName,
|
|
123
224
|
onElementLoad: () => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
225
|
+
clearTimeout(tracking.current.timeoutLoad);
|
|
226
|
+
tracking.current.endTime = Date.now();
|
|
227
|
+
tracking.current.timeoutInteraction?.cancel?.();
|
|
228
|
+
tracking.current.timeoutInteraction =
|
|
229
|
+
InteractionManager.runAfterInteractions(() => {
|
|
230
|
+
tracking.current.timeInteraction =
|
|
231
|
+
Date.now() - tracking.current.startTime;
|
|
232
|
+
});
|
|
233
|
+
tracking.current.timeoutLoad = setTimeout(() => {
|
|
234
|
+
if (tracking.current.timeLoad === 0) {
|
|
235
|
+
tracking.current.timeLoad =
|
|
236
|
+
tracking.current.endTime - tracking.current.startTime;
|
|
133
237
|
}
|
|
238
|
+
onScreenLoad();
|
|
239
|
+
onScreenInteraction();
|
|
134
240
|
}, 2000);
|
|
135
241
|
},
|
|
136
242
|
}}>
|
|
@@ -145,4 +251,78 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
145
251
|
);
|
|
146
252
|
};
|
|
147
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Empty screen for unvalidated screen name
|
|
256
|
+
* @constructor
|
|
257
|
+
*/
|
|
258
|
+
const EmptyScreen: React.FC = () => {
|
|
259
|
+
return (
|
|
260
|
+
<View
|
|
261
|
+
style={{
|
|
262
|
+
backgroundColor: Colors.black_01,
|
|
263
|
+
padding: Spacing.M,
|
|
264
|
+
borderRadius: Radius.M,
|
|
265
|
+
}}>
|
|
266
|
+
<Text typography={'header_m_bold'}>Unvalidated screen name</Text>
|
|
267
|
+
<Text
|
|
268
|
+
typography={'description_default_regular'}
|
|
269
|
+
style={{paddingVertical: Spacing.S}}>
|
|
270
|
+
Your screen has not been rendered because Platform has not detected the
|
|
271
|
+
screen name. Please migrate to support this feature.
|
|
272
|
+
</Text>
|
|
273
|
+
<Text typography={'header_default'} style={{width: '100%'}}>
|
|
274
|
+
Possible fixes:
|
|
275
|
+
</Text>
|
|
276
|
+
<View style={{marginLeft: Spacing.S}}>
|
|
277
|
+
<Text typography={'body_default_regular'}>1. Off webpack config</Text>
|
|
278
|
+
<Text typography={'body_default_regular'}>
|
|
279
|
+
2. Screen name refactoring
|
|
280
|
+
</Text>
|
|
281
|
+
<View style={{marginLeft: Spacing.S}}>
|
|
282
|
+
<Text
|
|
283
|
+
typography={'description_default_regular'}
|
|
284
|
+
style={{marginBottom: Spacing.S}}>
|
|
285
|
+
- Với các screen push/import dạng arrow function ={'>'} đổi thành
|
|
286
|
+
named function
|
|
287
|
+
</Text>
|
|
288
|
+
<Text
|
|
289
|
+
typography={'description_default_regular'}
|
|
290
|
+
style={{marginBottom: Spacing.S}}>
|
|
291
|
+
- Với các screen import dạng High Order Component ={'>'} rename
|
|
292
|
+
generic function thành named function
|
|
293
|
+
</Text>
|
|
294
|
+
<Text
|
|
295
|
+
typography={'description_default_regular'}
|
|
296
|
+
style={{marginBottom: Spacing.S}}>
|
|
297
|
+
- Với Tab Navigator, Platform sẽ lấy Tab Container làm screen name.
|
|
298
|
+
Trong trường hợp miniapp muốn track riêng action cho từng tab, tham
|
|
299
|
+
khảo theo docs
|
|
300
|
+
</Text>
|
|
301
|
+
</View>
|
|
302
|
+
</View>
|
|
303
|
+
<Text typography={'header_s_semibold'}>More information: </Text>
|
|
304
|
+
<Text
|
|
305
|
+
typography={'body_default_regular'}
|
|
306
|
+
color={Colors.blue_01}
|
|
307
|
+
onPress={() => {
|
|
308
|
+
Linking.openURL(
|
|
309
|
+
'https://gitlab.mservice.com.vn/momo-platform/mini-app/-/tree/vn.momo.uikits/dev/app'
|
|
310
|
+
);
|
|
311
|
+
}}>
|
|
312
|
+
Mini App: vn.momo.uikits/dev
|
|
313
|
+
</Text>
|
|
314
|
+
<Text
|
|
315
|
+
typography={'body_default_regular'}
|
|
316
|
+
color={Colors.blue_01}
|
|
317
|
+
onPress={() => {
|
|
318
|
+
Linking.openURL(
|
|
319
|
+
'https://docs.google.com/presentation/d/1bIFoh8gRXb6hsnGJz4O1Kxg4_oNikB1KuuEt2wULCDM/edit?usp=sharing'
|
|
320
|
+
);
|
|
321
|
+
}}>
|
|
322
|
+
https://docs.google.com/presentation/d/1bIFoh8gRXb6hsnGJz4O1Kxg4_oNikB1KuuEt2wULCDM/edit?usp=sharing
|
|
323
|
+
</Text>
|
|
324
|
+
</View>
|
|
325
|
+
);
|
|
326
|
+
};
|
|
327
|
+
|
|
148
328
|
export default StackScreen;
|
package/Application/index.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {Platform} from 'react-native';
|
|
2
|
+
import {createContext} from 'react';
|
|
2
3
|
import {NavigationContainer} from './NavigationContainer';
|
|
4
|
+
import Localize from './Localize';
|
|
3
5
|
import Screen from '../Layout/Screen';
|
|
4
6
|
import {
|
|
5
7
|
HeaderAnimated,
|
|
6
8
|
HeaderBackground,
|
|
7
9
|
HeaderCustom,
|
|
8
|
-
HeaderRightAction,
|
|
9
10
|
HeaderTitle,
|
|
10
11
|
NavigationButton,
|
|
12
|
+
HeaderRightAction,
|
|
11
13
|
} from './Components';
|
|
12
14
|
import BottomTab from './BottomTab';
|
|
13
|
-
import {createContext} from 'react';
|
|
14
15
|
import {defaultContext} from '../Consts';
|
|
15
16
|
|
|
16
17
|
const Context = createContext({});
|
|
@@ -26,12 +27,13 @@ export {
|
|
|
26
27
|
ScreenContext,
|
|
27
28
|
ComponentContext,
|
|
28
29
|
NavigationContainer,
|
|
30
|
+
Localize,
|
|
29
31
|
Screen,
|
|
30
32
|
BottomTab,
|
|
31
33
|
NavigationButton,
|
|
34
|
+
HeaderRightAction,
|
|
32
35
|
HeaderTitle,
|
|
33
36
|
HeaderBackground,
|
|
34
|
-
HeaderRightAction,
|
|
35
37
|
HeaderCustom,
|
|
36
38
|
HeaderAnimated,
|
|
37
39
|
};
|
package/Application/types.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import {EventArg} from '@react-navigation/core';
|
|
1
2
|
import {StackNavigationOptions} from '@react-navigation/stack';
|
|
2
3
|
import React from 'react';
|
|
3
|
-
import {Animated,
|
|
4
|
+
import {Animated, ViewProps} from 'react-native';
|
|
4
5
|
import {PopupNotifyProps} from '../Popup/types';
|
|
6
|
+
import Localize from './Localize';
|
|
5
7
|
import Navigation from './Navigation';
|
|
6
8
|
import Navigator from './Navigator';
|
|
7
9
|
|
|
@@ -70,16 +72,6 @@ export type Context = {
|
|
|
70
72
|
translate?: (key: string) => string;
|
|
71
73
|
};
|
|
72
74
|
|
|
73
|
-
export type MiniAppInfo = {
|
|
74
|
-
[key: string]: any;
|
|
75
|
-
code: string;
|
|
76
|
-
appId: string;
|
|
77
|
-
buildNumber: number;
|
|
78
|
-
flowPartnerId?: string;
|
|
79
|
-
toolkitConfig?: any;
|
|
80
|
-
fromCode?: string;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
75
|
export type LocalizationObject = {
|
|
84
76
|
vi: {
|
|
85
77
|
[key: string]: string;
|
|
@@ -94,8 +86,8 @@ export type NavigationContainerProps = {
|
|
|
94
86
|
options?: NavigationOptions;
|
|
95
87
|
theme: Theme;
|
|
96
88
|
maxApi: any;
|
|
97
|
-
localization?: LocalizationObject;
|
|
98
89
|
initialParams?: any;
|
|
90
|
+
localize: Localize;
|
|
99
91
|
};
|
|
100
92
|
|
|
101
93
|
export type NavigationScreenProps = {
|
|
@@ -110,26 +102,35 @@ export type ScreenParams = {
|
|
|
110
102
|
options?: NavigationOptions;
|
|
111
103
|
};
|
|
112
104
|
|
|
113
|
-
export
|
|
105
|
+
export type ModalParams = {
|
|
114
106
|
[key: string]: any;
|
|
107
|
+
screen: React.ComponentType;
|
|
115
108
|
onDismiss?: () => void;
|
|
116
109
|
barrierDismissible?: boolean;
|
|
117
|
-
}
|
|
110
|
+
};
|
|
118
111
|
|
|
119
|
-
export
|
|
112
|
+
export type BottomSheetParams = {
|
|
120
113
|
[key: string]: any;
|
|
121
|
-
|
|
114
|
+
screen: React.ComponentType;
|
|
115
|
+
options: {
|
|
116
|
+
title: string;
|
|
117
|
+
surface?: boolean;
|
|
118
|
+
};
|
|
119
|
+
useNativeModal?: boolean;
|
|
122
120
|
surface?: boolean;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
onDismiss?: (type?: string) => void;
|
|
122
|
+
barrierDismissible?: boolean;
|
|
123
|
+
draggable?: boolean;
|
|
124
|
+
useBottomInset?: boolean;
|
|
125
|
+
keyboardVerticalOffset?: number;
|
|
126
|
+
};
|
|
126
127
|
|
|
127
128
|
export type NavigationButtonProps = {
|
|
128
129
|
icon: string;
|
|
129
130
|
tintColor?: string;
|
|
130
131
|
useBorder?: boolean;
|
|
131
132
|
onPress: () => void;
|
|
132
|
-
badgeType?: 'dot' | 'number';
|
|
133
|
+
badgeType?: 'dot' | 'number' | 'dot-animation';
|
|
133
134
|
badgeValue?: number;
|
|
134
135
|
accessibilityLabel?: string;
|
|
135
136
|
};
|
|
@@ -137,7 +138,7 @@ export type NavigationButtonProps = {
|
|
|
137
138
|
export type PinnedToolType = {
|
|
138
139
|
key: string;
|
|
139
140
|
badgeValue?: number;
|
|
140
|
-
badgeType?: 'number' | 'dot';
|
|
141
|
+
badgeType?: 'number' | 'dot' | 'dot-animation';
|
|
141
142
|
};
|
|
142
143
|
|
|
143
144
|
export type RuntimeToolType = {
|
|
@@ -146,19 +147,29 @@ export type RuntimeToolType = {
|
|
|
146
147
|
key: string;
|
|
147
148
|
};
|
|
148
149
|
|
|
149
|
-
export interface NavigationOptions
|
|
150
|
+
export interface NavigationOptions
|
|
151
|
+
extends Omit<StackNavigationOptions, 'headerRight'> {
|
|
150
152
|
preventBack?: PopupNotifyProps;
|
|
151
153
|
onPressLeftHeader?: () => void;
|
|
152
154
|
surface?: boolean;
|
|
153
155
|
hiddenBack?: boolean;
|
|
154
156
|
customTitle?: TitleCustomProps;
|
|
155
|
-
|
|
156
|
-
pinnedTool?: PinnedToolType;
|
|
157
|
-
runtimeTools?: RuntimeToolType[];
|
|
158
|
-
preventClose?: PopupNotifyProps;
|
|
159
|
-
};
|
|
157
|
+
headerRight?: HeaderRightToolkit | HeaderRightActions | any;
|
|
160
158
|
}
|
|
161
159
|
|
|
160
|
+
export type HeaderRightToolkit = {
|
|
161
|
+
type?: 'toolkit';
|
|
162
|
+
pinnedTool?: PinnedToolType;
|
|
163
|
+
runtimeTools?: RuntimeToolType[];
|
|
164
|
+
preventClose?: PopupNotifyProps;
|
|
165
|
+
useMore?: boolean;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export type HeaderRightActions = {
|
|
169
|
+
type?: 'icon';
|
|
170
|
+
buttons: NavigationButtonProps[];
|
|
171
|
+
};
|
|
172
|
+
|
|
162
173
|
export interface HeaderBackProps extends NavigationButtonProps {
|
|
163
174
|
preventBack?: PopupNotifyProps;
|
|
164
175
|
onPressLeftHeader?: () => void;
|
|
@@ -199,6 +210,12 @@ export type BottomTabItemProps = {
|
|
|
199
210
|
badgeLabel?: string | number;
|
|
200
211
|
screen: Screen;
|
|
201
212
|
options: NavigationOptions;
|
|
213
|
+
initialParams?: any;
|
|
214
|
+
listeners?: {
|
|
215
|
+
tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
|
|
216
|
+
focus?: (e: EventArg<'focus', false, unknown>) => void;
|
|
217
|
+
blur?: (e: EventArg<'blur', false, unknown>) => void;
|
|
218
|
+
};
|
|
202
219
|
};
|
|
203
220
|
|
|
204
221
|
export type BottomTabProps = {
|
|
@@ -207,8 +224,9 @@ export type BottomTabProps = {
|
|
|
207
224
|
initialRouteName?: string;
|
|
208
225
|
navigation: Navigation;
|
|
209
226
|
listeners?: {
|
|
210
|
-
tabPress?:
|
|
211
|
-
focus?:
|
|
227
|
+
tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
|
|
228
|
+
focus?: (e: EventArg<'focus', false, unknown>) => void;
|
|
229
|
+
blur?: (e: EventArg<'blur', false, unknown>) => void;
|
|
212
230
|
};
|
|
213
231
|
floatingButton?: FloatingButtonProps;
|
|
214
232
|
};
|
package/Application/utils.tsx
CHANGED
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
HeaderBackground,
|
|
8
8
|
HeaderCustom,
|
|
9
9
|
HeaderLeft,
|
|
10
|
+
HeaderRight,
|
|
10
11
|
HeaderTitle,
|
|
11
|
-
HeaderToolkitAction,
|
|
12
12
|
} from './Components';
|
|
13
|
-
import {NavigationOptions
|
|
13
|
+
import {NavigationOptions} from './types';
|
|
14
14
|
import {Colors} from '../Consts';
|
|
15
|
+
import Navigation from './Navigation';
|
|
16
|
+
import {LayoutChangeEvent} from 'react-native';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* default options for stack screen
|
|
@@ -22,7 +24,7 @@ const getStackOptions = (): StackNavigationOptions => {
|
|
|
22
24
|
headerTitle: HeaderTitle,
|
|
23
25
|
headerBackground: (props: any) => <HeaderBackground {...props} />,
|
|
24
26
|
headerLeft: (props: any) => <HeaderLeft {...props} />,
|
|
25
|
-
headerRight: (props: any) => <
|
|
27
|
+
headerRight: (props: any) => <HeaderRight {...props} />,
|
|
26
28
|
headerTintColor: Colors.black_01,
|
|
27
29
|
};
|
|
28
30
|
};
|
|
@@ -72,33 +74,42 @@ const getModalOptions = (): StackNavigationOptions => {
|
|
|
72
74
|
/**
|
|
73
75
|
* build react-navigation options
|
|
74
76
|
*/
|
|
75
|
-
const getOptions = (params: NavigationOptions,
|
|
77
|
+
const getOptions = (params: NavigationOptions, navigation?: Navigation) => {
|
|
76
78
|
let options = {};
|
|
77
79
|
|
|
80
|
+
/**
|
|
81
|
+
* left header factory
|
|
82
|
+
*/
|
|
78
83
|
if (
|
|
79
84
|
typeof params.onPressLeftHeader === 'function' ||
|
|
80
85
|
params.preventBack !== undefined ||
|
|
81
86
|
typeof params.hiddenBack === 'boolean'
|
|
82
87
|
) {
|
|
88
|
+
let headerLeft: any = (props: any) => (
|
|
89
|
+
<HeaderLeft
|
|
90
|
+
{...props}
|
|
91
|
+
preventBack={params.preventBack}
|
|
92
|
+
onPressLeftHeader={params.onPressLeftHeader}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
if (params.hiddenBack) {
|
|
96
|
+
headerLeft = null;
|
|
97
|
+
}
|
|
83
98
|
options = {
|
|
84
99
|
...options,
|
|
85
|
-
headerLeft
|
|
86
|
-
? null
|
|
87
|
-
: (props: any) => (
|
|
88
|
-
<HeaderLeft
|
|
89
|
-
{...props}
|
|
90
|
-
preventBack={params.preventBack}
|
|
91
|
-
onPressLeftHeader={params.onPressLeftHeader}
|
|
92
|
-
/>
|
|
93
|
-
),
|
|
100
|
+
headerLeft,
|
|
94
101
|
};
|
|
95
102
|
}
|
|
96
103
|
|
|
97
|
-
|
|
104
|
+
/**
|
|
105
|
+
* surface header style
|
|
106
|
+
*/
|
|
107
|
+
if (typeof params.surface === 'boolean') {
|
|
108
|
+
console.warn('surface options is deprecated, headerType instead in screen');
|
|
98
109
|
if (params.surface) {
|
|
99
110
|
options = {
|
|
100
111
|
...options,
|
|
101
|
-
headerTintColor:
|
|
112
|
+
headerTintColor: Colors.black_17,
|
|
102
113
|
headerBackground: () => (
|
|
103
114
|
<HeaderBackground image={null} useSurface={true} />
|
|
104
115
|
),
|
|
@@ -112,7 +123,13 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
|
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
125
|
|
|
126
|
+
/**
|
|
127
|
+
* custom title
|
|
128
|
+
*/
|
|
115
129
|
if (params.customTitle) {
|
|
130
|
+
console.warn(
|
|
131
|
+
'customTitle options is deprecated, please used headerTitle instead'
|
|
132
|
+
);
|
|
116
133
|
options = {
|
|
117
134
|
...options,
|
|
118
135
|
headerTitleAlign: 'left',
|
|
@@ -122,12 +139,37 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
|
|
|
122
139
|
};
|
|
123
140
|
}
|
|
124
141
|
|
|
125
|
-
|
|
142
|
+
/**
|
|
143
|
+
* header right
|
|
144
|
+
*/
|
|
145
|
+
if (params.headerRight) {
|
|
146
|
+
let headerRight: any = (props: any) => {
|
|
147
|
+
return (
|
|
148
|
+
<HeaderRight
|
|
149
|
+
{...props}
|
|
150
|
+
{...params.headerRight}
|
|
151
|
+
onLayout={(e: LayoutChangeEvent) => {
|
|
152
|
+
navigation?.onHeaderRightChange?.(e.nativeEvent.layout.width);
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
if (typeof params.headerRight === 'function') {
|
|
158
|
+
headerRight = (props: any) => {
|
|
159
|
+
return (
|
|
160
|
+
<HeaderRight
|
|
161
|
+
{...props}
|
|
162
|
+
onLayout={(e: LayoutChangeEvent) => {
|
|
163
|
+
navigation?.onHeaderRightChange?.(e.nativeEvent.layout.width);
|
|
164
|
+
}}>
|
|
165
|
+
{params.headerRight(props)}
|
|
166
|
+
</HeaderRight>
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
126
170
|
options = {
|
|
127
171
|
...options,
|
|
128
|
-
headerRight
|
|
129
|
-
return <HeaderToolkitAction {...params.toolkitParams} {...props} />;
|
|
130
|
-
},
|
|
172
|
+
headerRight,
|
|
131
173
|
};
|
|
132
174
|
}
|
|
133
175
|
|
package/Assets/icon_bank.json
CHANGED