@momo-kits/foundation 0.92.26-beta.23 → 0.92.26-beta.25
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/BottomTab/index.tsx +2 -1
- package/Application/Components.tsx +39 -241
- package/Application/ModalScreen.tsx +2 -2
- package/Application/Navigation.ts +18 -4
- package/Application/StackScreen.tsx +22 -16
- package/Application/index.ts +2 -0
- package/Application/types.ts +6 -16
- package/Application/utils.tsx +18 -60
- package/Button/index.tsx +1 -0
- package/Input/Input.tsx +42 -15
- package/Input/InputDropDown.tsx +61 -31
- package/Input/InputMoney.tsx +45 -2
- package/Input/InputOTP.tsx +4 -4
- package/Input/InputSearch.tsx +154 -250
- package/Input/index.tsx +49 -89
- package/Input/styles.ts +3 -10
- package/Layout/Screen.tsx +92 -176
- package/Layout/styles.ts +6 -0
- package/Layout/types.ts +1 -1
- package/code-scanner.js +4 -4
- package/package.json +1 -1
- package/verify.js +25 -37
- package/Input/TextTyping.tsx +0 -113
|
@@ -17,9 +17,10 @@ const Tab = createBottomTabNavigator();
|
|
|
17
17
|
const Stack = createStackNavigator();
|
|
18
18
|
|
|
19
19
|
const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
|
|
20
|
+
const {theme} = useContext(ApplicationContext);
|
|
20
21
|
let options = {};
|
|
21
22
|
if (route.params?.options) {
|
|
22
|
-
options = getOptions(route.params?.options);
|
|
23
|
+
options = getOptions(route.params?.options, theme);
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
if (route.params?.nested) {
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import React, {
|
|
2
|
-
|
|
2
|
+
Fragment,
|
|
3
3
|
useCallback,
|
|
4
4
|
useContext,
|
|
5
5
|
useEffect,
|
|
6
|
-
useRef,
|
|
7
6
|
useState,
|
|
8
7
|
} from 'react';
|
|
9
8
|
import {
|
|
10
9
|
Animated,
|
|
11
10
|
BackHandler,
|
|
12
11
|
DeviceEventEmitter,
|
|
13
|
-
Dimensions,
|
|
14
12
|
StatusBar,
|
|
15
13
|
StyleSheet,
|
|
16
14
|
TouchableOpacity,
|
|
@@ -31,17 +29,7 @@ import {scaleSize, Text} from '../Text';
|
|
|
31
29
|
import {Icon} from '../Icon';
|
|
32
30
|
import {PopupNotify} from '../Popup';
|
|
33
31
|
import {Badge, BadgeDot} from '../Badge';
|
|
34
|
-
import {HeaderType} from '../Layout/types';
|
|
35
|
-
import Navigation from './Navigation';
|
|
36
|
-
import {InputRef, InputSearch, InputSearchProps} from '../Input';
|
|
37
32
|
|
|
38
|
-
const SCREEN_PADDING = 12;
|
|
39
|
-
const BACK_WIDTH = 28;
|
|
40
|
-
const {width: screenWidth} = Dimensions.get('window');
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* default navigation button used header nav
|
|
44
|
-
*/
|
|
45
33
|
const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
46
34
|
icon,
|
|
47
35
|
tintColor,
|
|
@@ -93,18 +81,13 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
|
93
81
|
);
|
|
94
82
|
};
|
|
95
83
|
|
|
96
|
-
/**
|
|
97
|
-
* default header title used for nav
|
|
98
|
-
*/
|
|
99
84
|
const HeaderTitle: React.FC<any> = props => {
|
|
100
85
|
const {theme} = useContext(ApplicationContext);
|
|
101
|
-
const opacity = props.animatedValue?.interpolate(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
);
|
|
86
|
+
const opacity = props.animatedValue?.interpolate({
|
|
87
|
+
inputRange: [0, 200],
|
|
88
|
+
outputRange: [0, 1],
|
|
89
|
+
extrapolate: 'clamp',
|
|
90
|
+
});
|
|
108
91
|
|
|
109
92
|
return (
|
|
110
93
|
<Animated.Text
|
|
@@ -118,9 +101,6 @@ const HeaderTitle: React.FC<any> = props => {
|
|
|
118
101
|
);
|
|
119
102
|
};
|
|
120
103
|
|
|
121
|
-
/**
|
|
122
|
-
* default header left used for nav
|
|
123
|
-
*/
|
|
124
104
|
const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
125
105
|
tintColor,
|
|
126
106
|
preventBack,
|
|
@@ -133,7 +113,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
133
113
|
useEffect(() => {
|
|
134
114
|
const backHandler = BackHandler.addEventListener(
|
|
135
115
|
'hardwareBackPress',
|
|
136
|
-
goBackSafe
|
|
116
|
+
goBackSafe,
|
|
137
117
|
);
|
|
138
118
|
|
|
139
119
|
return () => backHandler.remove();
|
|
@@ -188,7 +168,6 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
188
168
|
}
|
|
189
169
|
return true;
|
|
190
170
|
};
|
|
191
|
-
|
|
192
171
|
return (
|
|
193
172
|
<View style={styles.headerLeft}>
|
|
194
173
|
<NavigationButton
|
|
@@ -202,9 +181,6 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
202
181
|
);
|
|
203
182
|
};
|
|
204
183
|
|
|
205
|
-
/**
|
|
206
|
-
* header background for default
|
|
207
|
-
*/
|
|
208
184
|
const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
209
185
|
image,
|
|
210
186
|
animatedValue,
|
|
@@ -253,10 +229,6 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
253
229
|
);
|
|
254
230
|
};
|
|
255
231
|
|
|
256
|
-
/**
|
|
257
|
-
* Header custom with image, title, subtitle
|
|
258
|
-
* @constructor
|
|
259
|
-
*/
|
|
260
232
|
const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
261
233
|
title,
|
|
262
234
|
subTitle,
|
|
@@ -291,42 +263,37 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
|
291
263
|
return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
|
|
292
264
|
};
|
|
293
265
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
buttons = buttons.slice(0, 3);
|
|
266
|
+
const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
|
|
267
|
+
const validateType = (child: React.ReactElement) => {
|
|
268
|
+
const valid = child?.type === NavigationButton || child?.type === Fragment;
|
|
269
|
+
if (__DEV__ && !valid) {
|
|
270
|
+
console.warn(
|
|
271
|
+
'HeaderRightAction contains element type of NavigationButton, Please check again.',
|
|
272
|
+
);
|
|
302
273
|
}
|
|
274
|
+
return child;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const renderAction = () => {
|
|
278
|
+
if (Array.isArray(children)) {
|
|
279
|
+
return children.map((child, index) => {
|
|
280
|
+
return (
|
|
281
|
+
<View key={`HeaderRightAction ${index}`} style={styles.headerButton}>
|
|
282
|
+
{React.cloneElement(validateType(child), {...restProps})}
|
|
283
|
+
</View>
|
|
284
|
+
);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
303
288
|
return (
|
|
304
|
-
<View style={styles.
|
|
305
|
-
{
|
|
306
|
-
return (
|
|
307
|
-
<View
|
|
308
|
-
key={`HeaderRightAction ${index}`}
|
|
309
|
-
style={{
|
|
310
|
-
marginLeft: index !== 0 ? Spacing.S : 0,
|
|
311
|
-
}}>
|
|
312
|
-
<NavigationButton {...item} tintColor={props?.tintColor} />
|
|
313
|
-
</View>
|
|
314
|
-
);
|
|
315
|
-
})}
|
|
289
|
+
<View style={styles.headerButton}>
|
|
290
|
+
{React.cloneElement(validateType(children), {...restProps})}
|
|
316
291
|
</View>
|
|
317
292
|
);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return (
|
|
321
|
-
<View style={styles.headerRightButton} onLayout={onLayout}>
|
|
322
|
-
{children ?? <HeaderToolkitAction {...props} />}
|
|
323
|
-
</View>
|
|
324
|
-
);
|
|
293
|
+
};
|
|
294
|
+
return <View style={styles.headerRightButton}>{renderAction()}</View>;
|
|
325
295
|
};
|
|
326
296
|
|
|
327
|
-
/**
|
|
328
|
-
* Header toolkit action
|
|
329
|
-
*/
|
|
330
297
|
const HeaderToolkitAction: React.FC<any> = ({
|
|
331
298
|
tintColor,
|
|
332
299
|
pinnedTool,
|
|
@@ -360,7 +327,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
360
327
|
(config: any) => {
|
|
361
328
|
navigator.toolkitConfig = config;
|
|
362
329
|
setToolConfig(navigator?.toolkitConfig);
|
|
363
|
-
}
|
|
330
|
+
},
|
|
364
331
|
);
|
|
365
332
|
};
|
|
366
333
|
|
|
@@ -373,7 +340,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
373
340
|
const {item} = res;
|
|
374
341
|
navigator?.toolkitCallback?.(item);
|
|
375
342
|
getToolkitConfig();
|
|
376
|
-
}
|
|
343
|
+
},
|
|
377
344
|
);
|
|
378
345
|
};
|
|
379
346
|
|
|
@@ -390,7 +357,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
390
357
|
navigator?.maxApi?.dispatchFunction?.(
|
|
391
358
|
'dismiss',
|
|
392
359
|
undefined,
|
|
393
|
-
undefined
|
|
360
|
+
undefined,
|
|
394
361
|
);
|
|
395
362
|
},
|
|
396
363
|
}}
|
|
@@ -421,7 +388,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
421
388
|
[pinTool?.key],
|
|
422
389
|
() => {
|
|
423
390
|
getToolkitConfig();
|
|
424
|
-
}
|
|
391
|
+
},
|
|
425
392
|
);
|
|
426
393
|
navigator?.toolkitCallback?.(pinTool.key);
|
|
427
394
|
}}
|
|
@@ -430,7 +397,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
430
397
|
};
|
|
431
398
|
if (toolConfig) {
|
|
432
399
|
return (
|
|
433
|
-
<View style={
|
|
400
|
+
<View style={styles.headerRightButton}>
|
|
434
401
|
{renderPinnedTool()}
|
|
435
402
|
<View
|
|
436
403
|
style={[
|
|
@@ -438,7 +405,6 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
438
405
|
{
|
|
439
406
|
backgroundColor: backgroundColor ?? '#00000066',
|
|
440
407
|
borderWidth: backgroundColor ? 0.5 : 0,
|
|
441
|
-
marginLeft: renderPinnedTool() ? Spacing.S : 0,
|
|
442
408
|
},
|
|
443
409
|
]}>
|
|
444
410
|
<TouchableOpacity
|
|
@@ -464,9 +430,6 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
464
430
|
return <View />;
|
|
465
431
|
};
|
|
466
432
|
|
|
467
|
-
/**
|
|
468
|
-
* default header banner for header animated
|
|
469
|
-
*/
|
|
470
433
|
const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
471
434
|
animatedValue,
|
|
472
435
|
image,
|
|
@@ -507,160 +470,6 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
|
507
470
|
);
|
|
508
471
|
};
|
|
509
472
|
|
|
510
|
-
/**
|
|
511
|
-
* Header extended with background image
|
|
512
|
-
* @constructor
|
|
513
|
-
*/
|
|
514
|
-
const HeaderExtendHeader: React.FC<{
|
|
515
|
-
headerType?: HeaderType;
|
|
516
|
-
animatedValue: Animated.Value;
|
|
517
|
-
heightHeader: number;
|
|
518
|
-
inputSearchProps?: InputSearchProps;
|
|
519
|
-
inputSearchRef?: Ref<InputRef>;
|
|
520
|
-
navigation?: Navigation;
|
|
521
|
-
}> = ({
|
|
522
|
-
headerType = 'default',
|
|
523
|
-
animatedValue,
|
|
524
|
-
heightHeader,
|
|
525
|
-
inputSearchProps,
|
|
526
|
-
inputSearchRef,
|
|
527
|
-
navigation,
|
|
528
|
-
}) => {
|
|
529
|
-
const {theme} = useContext(ApplicationContext);
|
|
530
|
-
const [rightSpace, setRightSpace] = useState(0);
|
|
531
|
-
const animated = useRef(new Animated.Value(0));
|
|
532
|
-
|
|
533
|
-
useEffect(() => {
|
|
534
|
-
const listener = animatedValue.addListener(({value}) => {
|
|
535
|
-
animated.current.setValue(value);
|
|
536
|
-
});
|
|
537
|
-
return () => {
|
|
538
|
-
animatedValue?.removeListener(listener);
|
|
539
|
-
};
|
|
540
|
-
}, []);
|
|
541
|
-
|
|
542
|
-
const height = animated.current.interpolate({
|
|
543
|
-
inputRange: [0, 100],
|
|
544
|
-
outputRange: [heightHeader + 52, heightHeader],
|
|
545
|
-
extrapolate: 'clamp',
|
|
546
|
-
});
|
|
547
|
-
|
|
548
|
-
const translateX = animated.current.interpolate({
|
|
549
|
-
inputRange: [0, 100],
|
|
550
|
-
outputRange: [SCREEN_PADDING, BACK_WIDTH + SCREEN_PADDING * 2],
|
|
551
|
-
extrapolate: 'clamp',
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
if (navigation) {
|
|
555
|
-
navigation.onHeaderRightChange = (width: number) => {
|
|
556
|
-
setRightSpace(width);
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
const renderInputView = (hasColorBG: boolean = false) => {
|
|
561
|
-
return (
|
|
562
|
-
<Animated.View
|
|
563
|
-
style={{
|
|
564
|
-
justifyContent: 'flex-end',
|
|
565
|
-
height,
|
|
566
|
-
}}>
|
|
567
|
-
<Animated.View
|
|
568
|
-
style={{
|
|
569
|
-
transform: [{translateX}],
|
|
570
|
-
marginVertical: Spacing.S,
|
|
571
|
-
width: animated.current.interpolate({
|
|
572
|
-
inputRange: [0, 100],
|
|
573
|
-
outputRange: [
|
|
574
|
-
screenWidth - SCREEN_PADDING * 2,
|
|
575
|
-
screenWidth - SCREEN_PADDING * 3 - BACK_WIDTH - rightSpace,
|
|
576
|
-
],
|
|
577
|
-
extrapolate: 'clamp',
|
|
578
|
-
}),
|
|
579
|
-
}}>
|
|
580
|
-
<InputSearch
|
|
581
|
-
{...inputSearchProps}
|
|
582
|
-
ref={inputSearchRef}
|
|
583
|
-
hasColorBG={hasColorBG}
|
|
584
|
-
showButtonText={false}
|
|
585
|
-
/>
|
|
586
|
-
</Animated.View>
|
|
587
|
-
</Animated.View>
|
|
588
|
-
);
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
if (inputSearchProps) {
|
|
592
|
-
if (headerType === 'surface') {
|
|
593
|
-
return (
|
|
594
|
-
<>
|
|
595
|
-
<Animated.View
|
|
596
|
-
style={[
|
|
597
|
-
styles.headerBox,
|
|
598
|
-
{
|
|
599
|
-
backgroundColor: theme.colors.background.surface,
|
|
600
|
-
borderBottomWidth: 1,
|
|
601
|
-
borderColor: theme.colors.border.default,
|
|
602
|
-
height,
|
|
603
|
-
},
|
|
604
|
-
]}
|
|
605
|
-
/>
|
|
606
|
-
{renderInputView(true)}
|
|
607
|
-
</>
|
|
608
|
-
);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
if (headerType === 'extended') {
|
|
612
|
-
return (
|
|
613
|
-
<>
|
|
614
|
-
<Animated.View
|
|
615
|
-
style={[
|
|
616
|
-
styles.headerBox,
|
|
617
|
-
{
|
|
618
|
-
height,
|
|
619
|
-
},
|
|
620
|
-
]}>
|
|
621
|
-
<Image
|
|
622
|
-
source={{
|
|
623
|
-
uri: theme.assets?.headerBackground,
|
|
624
|
-
}}
|
|
625
|
-
style={styles.headerBackground}
|
|
626
|
-
/>
|
|
627
|
-
</Animated.View>
|
|
628
|
-
{renderInputView()}
|
|
629
|
-
</>
|
|
630
|
-
);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
return (
|
|
634
|
-
<>
|
|
635
|
-
<View style={[styles.headerBox, {height: heightHeader}]}>
|
|
636
|
-
<Image
|
|
637
|
-
source={{
|
|
638
|
-
uri: theme.assets?.headerBackground,
|
|
639
|
-
}}
|
|
640
|
-
style={styles.headerBackground}
|
|
641
|
-
/>
|
|
642
|
-
</View>
|
|
643
|
-
{renderInputView()}
|
|
644
|
-
</>
|
|
645
|
-
);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
if (headerType === 'extended') {
|
|
649
|
-
return (
|
|
650
|
-
<View style={{minHeight: heightHeader}}>
|
|
651
|
-
<Image
|
|
652
|
-
source={{
|
|
653
|
-
uri: theme.assets?.headerBackground,
|
|
654
|
-
}}
|
|
655
|
-
style={styles.extendedHeader}
|
|
656
|
-
/>
|
|
657
|
-
</View>
|
|
658
|
-
);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
return <View />;
|
|
662
|
-
};
|
|
663
|
-
|
|
664
473
|
const styles = StyleSheet.create({
|
|
665
474
|
navigationButton: {
|
|
666
475
|
height: 28,
|
|
@@ -700,6 +509,7 @@ const styles = StyleSheet.create({
|
|
|
700
509
|
paddingRight: Spacing.M,
|
|
701
510
|
},
|
|
702
511
|
toolkitContainer: {
|
|
512
|
+
marginLeft: Spacing.S,
|
|
703
513
|
padding: Spacing.XS,
|
|
704
514
|
height: 28,
|
|
705
515
|
borderRadius: 14,
|
|
@@ -731,17 +541,6 @@ const styles = StyleSheet.create({
|
|
|
731
541
|
top: -Spacing.XS,
|
|
732
542
|
right: -Spacing.XS,
|
|
733
543
|
},
|
|
734
|
-
extendedHeader: {
|
|
735
|
-
aspectRatio: 1.75,
|
|
736
|
-
position: 'absolute',
|
|
737
|
-
width: '100%',
|
|
738
|
-
height: 210,
|
|
739
|
-
},
|
|
740
|
-
headerBox: {
|
|
741
|
-
width: '100%',
|
|
742
|
-
position: 'absolute',
|
|
743
|
-
overflow: 'hidden',
|
|
744
|
-
},
|
|
745
544
|
});
|
|
746
545
|
|
|
747
546
|
export {
|
|
@@ -749,9 +548,8 @@ export {
|
|
|
749
548
|
HeaderTitle,
|
|
750
549
|
HeaderLeft,
|
|
751
550
|
HeaderBackground,
|
|
551
|
+
HeaderRightAction,
|
|
752
552
|
HeaderToolkitAction,
|
|
753
553
|
HeaderCustom,
|
|
754
554
|
HeaderAnimated,
|
|
755
|
-
HeaderRight,
|
|
756
|
-
HeaderExtendHeader,
|
|
757
555
|
};
|
|
@@ -21,10 +21,10 @@ const ModalScreen: React.FC<any> = props => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const Modal: React.FC<ModalParams> = props => {
|
|
24
|
-
const {navigator} = useContext(ApplicationContext);
|
|
24
|
+
const {theme, navigator} = useContext(ApplicationContext);
|
|
25
25
|
const {screen, barrierDismissible} = props.route.params;
|
|
26
26
|
const Component = useRef(screen).current;
|
|
27
|
-
const navigation = new Navigation(props.navigation);
|
|
27
|
+
const navigation = new Navigation(props.navigation, theme);
|
|
28
28
|
const params = {
|
|
29
29
|
...props.route.params,
|
|
30
30
|
navigation,
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import {NavigationProp} from '@react-navigation/native';
|
|
2
|
-
import {NavigationOptions} from './types';
|
|
3
|
+
import {NavigationOptions, Theme} from './types';
|
|
4
|
+
import {HeaderRightAction} from './index';
|
|
3
5
|
import {getOptions} from './utils';
|
|
6
|
+
import {HeaderToolkitAction} from './Components';
|
|
4
7
|
|
|
5
8
|
class Navigation {
|
|
6
9
|
instance: NavigationProp<any>;
|
|
7
|
-
|
|
10
|
+
readonly theme: Theme;
|
|
8
11
|
|
|
9
|
-
constructor(instance: any) {
|
|
12
|
+
constructor(instance: any, theme: Theme) {
|
|
10
13
|
this.instance = instance;
|
|
14
|
+
this.theme = theme;
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
/**
|
|
@@ -15,6 +19,16 @@ class Navigation {
|
|
|
15
19
|
* @param params
|
|
16
20
|
*/
|
|
17
21
|
private filterParams = (params: NavigationOptions) => {
|
|
22
|
+
if (params.headerRight) {
|
|
23
|
+
const headerRight = params.headerRight?.({}) as React.ReactElement;
|
|
24
|
+
const type = headerRight?.type;
|
|
25
|
+
if (type !== HeaderRightAction && type !== HeaderToolkitAction) {
|
|
26
|
+
console.warn(
|
|
27
|
+
'headerRight contains element type of HeaderRightAction | HeaderToolkitAction, Please check again.',
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
18
32
|
if (params.headerLeft) {
|
|
19
33
|
console.warn('headerLeft not allow override render by design system!');
|
|
20
34
|
delete params.headerLeft;
|
|
@@ -28,7 +42,7 @@ class Navigation {
|
|
|
28
42
|
* @param params
|
|
29
43
|
*/
|
|
30
44
|
setOptions = (params: NavigationOptions) => {
|
|
31
|
-
params = getOptions(this.filterParams(params), this);
|
|
45
|
+
params = getOptions(this.filterParams(params), this.theme);
|
|
32
46
|
this.instance.setOptions(params);
|
|
33
47
|
};
|
|
34
48
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useLayoutEffect, useRef} from 'react';
|
|
2
2
|
import {useHeaderHeight} from '@react-navigation/stack';
|
|
3
|
-
import {InteractionManager, Linking, View} from 'react-native';
|
|
3
|
+
import {Alert, InteractionManager, Linking, View} from 'react-native';
|
|
4
4
|
import {ScreenParams} from './types';
|
|
5
5
|
import Navigation from './Navigation';
|
|
6
6
|
import {ApplicationContext, MiniAppContext, ScreenContext} from './index';
|
|
@@ -88,7 +88,7 @@ const EmptyScreen: React.FC = () => {
|
|
|
88
88
|
* @constructor
|
|
89
89
|
*/
|
|
90
90
|
const StackScreen: React.FC<ScreenParams> = props => {
|
|
91
|
-
const {showGrid, navigator} = useContext(ApplicationContext);
|
|
91
|
+
const {theme, showGrid, navigator} = useContext(ApplicationContext);
|
|
92
92
|
const startTime = useRef(Date.now());
|
|
93
93
|
const endTime = useRef(Date.now());
|
|
94
94
|
const timeLoad = useRef(0);
|
|
@@ -104,7 +104,7 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
104
104
|
const context = useContext<any>(MiniAppContext);
|
|
105
105
|
|
|
106
106
|
const {screen: Component, options, initialParams} = props.route.params;
|
|
107
|
-
const navigation = new Navigation(props.navigation);
|
|
107
|
+
const navigation = new Navigation(props.navigation, theme);
|
|
108
108
|
const heightHeader = useHeaderHeight();
|
|
109
109
|
|
|
110
110
|
const data = {
|
|
@@ -122,18 +122,9 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
122
122
|
* set options for screen
|
|
123
123
|
*/
|
|
124
124
|
useLayoutEffect(() => {
|
|
125
|
-
let defaultOptions = {
|
|
126
|
-
headerRight: {
|
|
127
|
-
type: 'toolkit',
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
125
|
if (options) {
|
|
131
|
-
|
|
132
|
-
...defaultOptions,
|
|
133
|
-
...options,
|
|
134
|
-
};
|
|
126
|
+
navigation.setOptions(options);
|
|
135
127
|
}
|
|
136
|
-
navigation.setOptions(defaultOptions);
|
|
137
128
|
}, [options]);
|
|
138
129
|
|
|
139
130
|
/**
|
|
@@ -155,6 +146,8 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
155
146
|
}, 5000);
|
|
156
147
|
|
|
157
148
|
return () => {
|
|
149
|
+
clearTimeout(tracked.current.timeoutLoad);
|
|
150
|
+
clearTimeout(tracked.current.timeoutInteraction);
|
|
158
151
|
onScreenLoad();
|
|
159
152
|
onScreenInteraction();
|
|
160
153
|
};
|
|
@@ -164,8 +157,10 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
164
157
|
* tracking for screen load
|
|
165
158
|
*/
|
|
166
159
|
const onScreenLoad = () => {
|
|
167
|
-
clearTimeout(tracked.current.timeoutLoad);
|
|
168
160
|
if (!tracked.current?.releaseLoad) {
|
|
161
|
+
if (timeLoad.current === 0) {
|
|
162
|
+
timeLoad.current = endTime.current - startTime.current;
|
|
163
|
+
}
|
|
169
164
|
context.autoTracking?.({
|
|
170
165
|
appId: context.appId,
|
|
171
166
|
code: context.code,
|
|
@@ -179,6 +174,9 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
179
174
|
appId: `auto - ${context.appId}`,
|
|
180
175
|
message: `${screenName} screen_load_time ${timeLoad.current}`,
|
|
181
176
|
});
|
|
177
|
+
if (timeLoad.current === 0 && context.enableAutoId) {
|
|
178
|
+
Alert.alert(screenName, "Can't get screen load time");
|
|
179
|
+
}
|
|
182
180
|
tracked.current.releaseLoad = true;
|
|
183
181
|
}
|
|
184
182
|
};
|
|
@@ -187,8 +185,10 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
187
185
|
* tracking for screen load
|
|
188
186
|
*/
|
|
189
187
|
const onScreenInteraction = () => {
|
|
190
|
-
clearTimeout(tracked.current.timeoutInteraction);
|
|
191
188
|
if (!tracked.current?.releaseInteraction) {
|
|
189
|
+
if (timeLoad.current === 0) {
|
|
190
|
+
timeLoad.current = endTime.current - startTime.current;
|
|
191
|
+
}
|
|
192
192
|
context.autoTracking?.({
|
|
193
193
|
appId: context.appId,
|
|
194
194
|
code: context.code,
|
|
@@ -203,6 +203,12 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
203
203
|
appId: `auto - ${context.appId}`,
|
|
204
204
|
message: `${screenName} screen_interaction_time ${timeInteraction.current}`,
|
|
205
205
|
});
|
|
206
|
+
if (
|
|
207
|
+
timeInteraction.current - timeLoad.current <= 0 &&
|
|
208
|
+
context.enableAutoId
|
|
209
|
+
) {
|
|
210
|
+
Alert.alert(screenName, "Can't get screen interaction time");
|
|
211
|
+
}
|
|
206
212
|
tracked.current.releaseInteraction = true;
|
|
207
213
|
}
|
|
208
214
|
};
|
|
@@ -212,12 +218,12 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
212
218
|
value={{
|
|
213
219
|
screenName,
|
|
214
220
|
onElementLoad: () => {
|
|
221
|
+
clearTimeout(timeoutLoad.current);
|
|
215
222
|
endTime.current = Date.now();
|
|
216
223
|
interaction.current?.cancel?.();
|
|
217
224
|
interaction.current = InteractionManager.runAfterInteractions(() => {
|
|
218
225
|
timeInteraction.current = Date.now() - startTime.current;
|
|
219
226
|
});
|
|
220
|
-
clearTimeout(timeoutLoad.current);
|
|
221
227
|
timeoutLoad.current = setTimeout(() => {
|
|
222
228
|
if (timeLoad.current === 0) {
|
|
223
229
|
timeLoad.current = endTime.current - startTime.current;
|
package/Application/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
HeaderAnimated,
|
|
6
6
|
HeaderBackground,
|
|
7
7
|
HeaderCustom,
|
|
8
|
+
HeaderRightAction,
|
|
8
9
|
HeaderTitle,
|
|
9
10
|
NavigationButton,
|
|
10
11
|
} from './Components';
|
|
@@ -30,6 +31,7 @@ export {
|
|
|
30
31
|
NavigationButton,
|
|
31
32
|
HeaderTitle,
|
|
32
33
|
HeaderBackground,
|
|
34
|
+
HeaderRightAction,
|
|
33
35
|
HeaderCustom,
|
|
34
36
|
HeaderAnimated,
|
|
35
37
|
};
|
package/Application/types.ts
CHANGED
|
@@ -146,29 +146,19 @@ export type RuntimeToolType = {
|
|
|
146
146
|
key: string;
|
|
147
147
|
};
|
|
148
148
|
|
|
149
|
-
export interface NavigationOptions
|
|
150
|
-
extends Omit<StackNavigationOptions, 'headerRight'> {
|
|
149
|
+
export interface NavigationOptions extends StackNavigationOptions {
|
|
151
150
|
preventBack?: PopupNotifyProps;
|
|
152
151
|
onPressLeftHeader?: () => void;
|
|
153
152
|
surface?: boolean;
|
|
154
153
|
hiddenBack?: boolean;
|
|
155
154
|
customTitle?: TitleCustomProps;
|
|
156
|
-
|
|
155
|
+
toolkitParams?: {
|
|
156
|
+
pinnedTool?: PinnedToolType;
|
|
157
|
+
runtimeTools?: RuntimeToolType[];
|
|
158
|
+
preventClose?: PopupNotifyProps;
|
|
159
|
+
};
|
|
157
160
|
}
|
|
158
161
|
|
|
159
|
-
export type HeaderRightToolkit = {
|
|
160
|
-
type?: 'toolkit';
|
|
161
|
-
pinnedTool?: PinnedToolType;
|
|
162
|
-
runtimeTools?: RuntimeToolType[];
|
|
163
|
-
preventClose?: PopupNotifyProps;
|
|
164
|
-
useMore?: boolean;
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
export type HeaderRightActions = {
|
|
168
|
-
type?: 'icon';
|
|
169
|
-
buttons: NavigationButtonProps[];
|
|
170
|
-
};
|
|
171
|
-
|
|
172
162
|
export interface HeaderBackProps extends NavigationButtonProps {
|
|
173
163
|
preventBack?: PopupNotifyProps;
|
|
174
164
|
onPressLeftHeader?: () => void;
|