@momo-kits/foundation 0.92.34 → 0.102.1
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 +1 -2
- package/Application/Components.tsx +270 -35
- package/Application/ModalScreen.tsx +2 -2
- package/Application/Navigation.ts +4 -18
- package/Application/StackScreen.tsx +29 -12
- package/Application/index.ts +2 -2
- package/Application/types.ts +16 -6
- package/Application/utils.tsx +60 -18
- package/Button/index.tsx +0 -1
- package/Input/InputOTP.tsx +4 -4
- package/Input/InputSearch.tsx +258 -153
- package/Input/TextTyping.tsx +113 -0
- package/Input/index.tsx +18 -0
- package/Input/styles.ts +12 -5
- package/Layout/Screen.tsx +167 -83
- package/Layout/styles.ts +0 -6
- package/Layout/types.ts +1 -1
- package/Pagination/PaginationScroll.tsx +2 -2
- package/Pagination/styles.ts +1 -1
- package/Popup/PopupNotify.tsx +1 -1
- package/package.json +1 -1
- package/publish.sh +6 -6
|
@@ -17,10 +17,9 @@ const Tab = createBottomTabNavigator();
|
|
|
17
17
|
const Stack = createStackNavigator();
|
|
18
18
|
|
|
19
19
|
const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
|
|
20
|
-
const {theme} = useContext(ApplicationContext);
|
|
21
20
|
let options = {};
|
|
22
21
|
if (route.params?.options) {
|
|
23
|
-
options = getOptions(route.params?.options
|
|
22
|
+
options = getOptions(route.params?.options);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
if (route.params?.nested) {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import React, {
|
|
2
|
-
|
|
2
|
+
Ref,
|
|
3
3
|
useCallback,
|
|
4
4
|
useContext,
|
|
5
5
|
useEffect,
|
|
6
|
+
useRef,
|
|
6
7
|
useState,
|
|
7
8
|
} from 'react';
|
|
8
9
|
import {
|
|
10
|
+
Alert,
|
|
9
11
|
Animated,
|
|
10
12
|
BackHandler,
|
|
11
13
|
DeviceEventEmitter,
|
|
14
|
+
Dimensions,
|
|
12
15
|
StatusBar,
|
|
13
16
|
StyleSheet,
|
|
14
17
|
TouchableOpacity,
|
|
@@ -29,7 +32,17 @@ import {scaleSize, Text} from '../Text';
|
|
|
29
32
|
import {Icon} from '../Icon';
|
|
30
33
|
import {PopupNotify} from '../Popup';
|
|
31
34
|
import {Badge, BadgeDot} from '../Badge';
|
|
35
|
+
import {HeaderType} from '../Layout/types';
|
|
36
|
+
import Navigation from './Navigation';
|
|
37
|
+
import {InputRef, InputSearch, InputSearchProps} from '../Input';
|
|
32
38
|
|
|
39
|
+
const SCREEN_PADDING = 12;
|
|
40
|
+
const BACK_WIDTH = 28;
|
|
41
|
+
const {width: screenWidth} = Dimensions.get('window');
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* default navigation button used header nav
|
|
45
|
+
*/
|
|
33
46
|
const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
34
47
|
icon,
|
|
35
48
|
tintColor,
|
|
@@ -81,13 +94,18 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
|
81
94
|
);
|
|
82
95
|
};
|
|
83
96
|
|
|
97
|
+
/**
|
|
98
|
+
* default header title used for nav
|
|
99
|
+
*/
|
|
84
100
|
const HeaderTitle: React.FC<any> = props => {
|
|
85
101
|
const {theme} = useContext(ApplicationContext);
|
|
86
|
-
const opacity = props.animatedValue?.interpolate(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
102
|
+
const opacity = props.animatedValue?.interpolate(
|
|
103
|
+
props.interpolate ?? {
|
|
104
|
+
inputRange: [0, 200],
|
|
105
|
+
outputRange: [0, 1],
|
|
106
|
+
extrapolate: 'clamp',
|
|
107
|
+
}
|
|
108
|
+
);
|
|
91
109
|
|
|
92
110
|
return (
|
|
93
111
|
<Animated.Text
|
|
@@ -101,6 +119,9 @@ const HeaderTitle: React.FC<any> = props => {
|
|
|
101
119
|
);
|
|
102
120
|
};
|
|
103
121
|
|
|
122
|
+
/**
|
|
123
|
+
* default header left used for nav
|
|
124
|
+
*/
|
|
104
125
|
const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
105
126
|
tintColor,
|
|
106
127
|
preventBack,
|
|
@@ -168,6 +189,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
168
189
|
}
|
|
169
190
|
return true;
|
|
170
191
|
};
|
|
192
|
+
|
|
171
193
|
return (
|
|
172
194
|
<View style={styles.headerLeft}>
|
|
173
195
|
<NavigationButton
|
|
@@ -181,6 +203,9 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
181
203
|
);
|
|
182
204
|
};
|
|
183
205
|
|
|
206
|
+
/**
|
|
207
|
+
* header background for default
|
|
208
|
+
*/
|
|
184
209
|
const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
185
210
|
image,
|
|
186
211
|
animatedValue,
|
|
@@ -229,6 +254,10 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
229
254
|
);
|
|
230
255
|
};
|
|
231
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Header custom with image, title, subtitle
|
|
259
|
+
* @constructor
|
|
260
|
+
*/
|
|
232
261
|
const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
233
262
|
title,
|
|
234
263
|
subTitle,
|
|
@@ -263,37 +292,42 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
|
263
292
|
return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
|
|
264
293
|
};
|
|
265
294
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
295
|
+
/**
|
|
296
|
+
* main component for header right
|
|
297
|
+
*/
|
|
298
|
+
const HeaderRight: React.FC<any> = ({type, children, onLayout, ...props}) => {
|
|
299
|
+
if (type === 'icon') {
|
|
300
|
+
let buttons = props?.buttons || [];
|
|
301
|
+
if (buttons?.length > 3) {
|
|
302
|
+
buttons = buttons.slice(0, 3);
|
|
273
303
|
}
|
|
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
|
-
|
|
288
304
|
return (
|
|
289
|
-
<View style={styles.
|
|
290
|
-
{
|
|
305
|
+
<View style={styles.headerRightButton} onLayout={onLayout}>
|
|
306
|
+
{buttons?.map?.((item: NavigationButtonProps, index: number) => {
|
|
307
|
+
return (
|
|
308
|
+
<View
|
|
309
|
+
key={`HeaderRightAction ${index}`}
|
|
310
|
+
style={{
|
|
311
|
+
marginLeft: index !== 0 ? Spacing.S : 0,
|
|
312
|
+
}}>
|
|
313
|
+
<NavigationButton {...item} tintColor={props?.tintColor} />
|
|
314
|
+
</View>
|
|
315
|
+
);
|
|
316
|
+
})}
|
|
291
317
|
</View>
|
|
292
318
|
);
|
|
293
|
-
}
|
|
294
|
-
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return (
|
|
322
|
+
<View style={styles.headerRightButton} onLayout={onLayout}>
|
|
323
|
+
{children ?? <HeaderToolkitAction {...props} />}
|
|
324
|
+
</View>
|
|
325
|
+
);
|
|
295
326
|
};
|
|
296
327
|
|
|
328
|
+
/**
|
|
329
|
+
* Header toolkit action
|
|
330
|
+
*/
|
|
297
331
|
const HeaderToolkitAction: React.FC<any> = ({
|
|
298
332
|
tintColor,
|
|
299
333
|
pinnedTool,
|
|
@@ -385,7 +419,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
385
419
|
onPress={() => {
|
|
386
420
|
navigator?.maxApi?.dispatchFunction?.(
|
|
387
421
|
'onToolAction',
|
|
388
|
-
|
|
422
|
+
{item: pinTool},
|
|
389
423
|
() => {
|
|
390
424
|
getToolkitConfig();
|
|
391
425
|
}
|
|
@@ -397,7 +431,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
397
431
|
};
|
|
398
432
|
if (toolConfig) {
|
|
399
433
|
return (
|
|
400
|
-
<View style={
|
|
434
|
+
<View style={Styles.row}>
|
|
401
435
|
{renderPinnedTool()}
|
|
402
436
|
<View
|
|
403
437
|
style={[
|
|
@@ -405,6 +439,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
405
439
|
{
|
|
406
440
|
backgroundColor: backgroundColor ?? '#00000066',
|
|
407
441
|
borderWidth: backgroundColor ? 0.5 : 0,
|
|
442
|
+
marginLeft: renderPinnedTool() ? Spacing.S : 0,
|
|
408
443
|
},
|
|
409
444
|
]}>
|
|
410
445
|
<TouchableOpacity
|
|
@@ -430,6 +465,9 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
430
465
|
return <View />;
|
|
431
466
|
};
|
|
432
467
|
|
|
468
|
+
/**
|
|
469
|
+
* default header banner for header animated
|
|
470
|
+
*/
|
|
433
471
|
const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
434
472
|
animatedValue,
|
|
435
473
|
image,
|
|
@@ -470,6 +508,191 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
|
470
508
|
);
|
|
471
509
|
};
|
|
472
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Header extended with background image
|
|
513
|
+
* @constructor
|
|
514
|
+
*/
|
|
515
|
+
const HeaderExtendHeader: React.FC<{
|
|
516
|
+
headerType?: HeaderType;
|
|
517
|
+
animatedValue: Animated.Value;
|
|
518
|
+
heightHeader: number;
|
|
519
|
+
inputSearchProps?: InputSearchProps;
|
|
520
|
+
inputSearchRef?: Ref<InputRef>;
|
|
521
|
+
navigation?: Navigation;
|
|
522
|
+
}> = ({
|
|
523
|
+
headerType = 'default',
|
|
524
|
+
animatedValue,
|
|
525
|
+
heightHeader,
|
|
526
|
+
inputSearchProps,
|
|
527
|
+
inputSearchRef,
|
|
528
|
+
navigation,
|
|
529
|
+
}) => {
|
|
530
|
+
const {theme} = useContext(ApplicationContext);
|
|
531
|
+
const [rightSpace, setRightSpace] = useState(0);
|
|
532
|
+
const animated = useRef(new Animated.Value(0));
|
|
533
|
+
|
|
534
|
+
useEffect(() => {
|
|
535
|
+
const listener = animatedValue.addListener(({value}) => {
|
|
536
|
+
animated.current.setValue(value);
|
|
537
|
+
});
|
|
538
|
+
return () => {
|
|
539
|
+
animatedValue?.removeListener(listener);
|
|
540
|
+
};
|
|
541
|
+
}, []);
|
|
542
|
+
|
|
543
|
+
const height = animated.current.interpolate({
|
|
544
|
+
inputRange: [0, 100],
|
|
545
|
+
outputRange: [heightHeader + 52, heightHeader],
|
|
546
|
+
extrapolate: 'clamp',
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
const translateX = animated.current.interpolate({
|
|
550
|
+
inputRange: [0, 100],
|
|
551
|
+
outputRange: [SCREEN_PADDING, BACK_WIDTH + SCREEN_PADDING * 2],
|
|
552
|
+
extrapolate: 'clamp',
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
if (navigation) {
|
|
556
|
+
navigation.onHeaderRightChange = (width: number) => {
|
|
557
|
+
setRightSpace(width);
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const renderInputView = (hasColorBG: boolean = false) => {
|
|
562
|
+
return (
|
|
563
|
+
<Animated.View
|
|
564
|
+
style={{
|
|
565
|
+
justifyContent: 'flex-end',
|
|
566
|
+
height,
|
|
567
|
+
}}>
|
|
568
|
+
<Animated.View
|
|
569
|
+
style={{
|
|
570
|
+
transform: [{translateX}],
|
|
571
|
+
marginVertical: Spacing.S,
|
|
572
|
+
width: animated.current.interpolate({
|
|
573
|
+
inputRange: [0, 100],
|
|
574
|
+
outputRange: [
|
|
575
|
+
screenWidth - SCREEN_PADDING * 2,
|
|
576
|
+
screenWidth - SCREEN_PADDING * 3 - BACK_WIDTH - rightSpace,
|
|
577
|
+
],
|
|
578
|
+
extrapolate: 'clamp',
|
|
579
|
+
}),
|
|
580
|
+
}}>
|
|
581
|
+
<InputSearch
|
|
582
|
+
{...inputSearchProps}
|
|
583
|
+
ref={inputSearchRef}
|
|
584
|
+
hasColorBG={hasColorBG}
|
|
585
|
+
showButtonText={false}
|
|
586
|
+
/>
|
|
587
|
+
</Animated.View>
|
|
588
|
+
</Animated.View>
|
|
589
|
+
);
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
if (inputSearchProps) {
|
|
593
|
+
if (headerType === 'surface') {
|
|
594
|
+
return (
|
|
595
|
+
<>
|
|
596
|
+
<Animated.View
|
|
597
|
+
style={[
|
|
598
|
+
styles.headerBox,
|
|
599
|
+
{
|
|
600
|
+
backgroundColor: theme.colors.background.surface,
|
|
601
|
+
borderBottomWidth: 1,
|
|
602
|
+
borderColor: theme.colors.border.default,
|
|
603
|
+
height,
|
|
604
|
+
},
|
|
605
|
+
]}
|
|
606
|
+
/>
|
|
607
|
+
{renderInputView(true)}
|
|
608
|
+
</>
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
if (headerType === 'extended') {
|
|
613
|
+
return (
|
|
614
|
+
<>
|
|
615
|
+
<Animated.View
|
|
616
|
+
style={[
|
|
617
|
+
styles.headerBox,
|
|
618
|
+
{
|
|
619
|
+
height,
|
|
620
|
+
},
|
|
621
|
+
]}>
|
|
622
|
+
<Image
|
|
623
|
+
source={{
|
|
624
|
+
uri: theme.assets?.headerBackground,
|
|
625
|
+
}}
|
|
626
|
+
style={styles.headerBackground}
|
|
627
|
+
/>
|
|
628
|
+
</Animated.View>
|
|
629
|
+
{renderInputView()}
|
|
630
|
+
</>
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
return (
|
|
635
|
+
<>
|
|
636
|
+
<View style={[styles.headerBox, {height: heightHeader}]}>
|
|
637
|
+
<Image
|
|
638
|
+
source={{
|
|
639
|
+
uri: theme.assets?.headerBackground,
|
|
640
|
+
}}
|
|
641
|
+
style={styles.headerBackground}
|
|
642
|
+
/>
|
|
643
|
+
</View>
|
|
644
|
+
{renderInputView()}
|
|
645
|
+
</>
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (headerType === 'extended') {
|
|
650
|
+
return (
|
|
651
|
+
<View style={{minHeight: heightHeader}}>
|
|
652
|
+
<Image
|
|
653
|
+
source={{
|
|
654
|
+
uri: theme.assets?.headerBackground,
|
|
655
|
+
}}
|
|
656
|
+
style={styles.extendedHeader}
|
|
657
|
+
/>
|
|
658
|
+
</View>
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
return <View />;
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
|
|
666
|
+
if (__DEV__) {
|
|
667
|
+
Alert.alert(
|
|
668
|
+
'HeaderRightAction',
|
|
669
|
+
'This component is deprecated, please use HeaderRight instead v0.92.34'
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
const validateType = (child: React.ReactElement) => {
|
|
673
|
+
return child;
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
const renderAction = () => {
|
|
677
|
+
if (Array.isArray(children)) {
|
|
678
|
+
return children.map((child, index) => {
|
|
679
|
+
return (
|
|
680
|
+
<View key={`HeaderRightAction ${index}`} style={styles.headerButton}>
|
|
681
|
+
{React.cloneElement(validateType(child), {...restProps})}
|
|
682
|
+
</View>
|
|
683
|
+
);
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
return (
|
|
688
|
+
<View style={styles.headerButton}>
|
|
689
|
+
{React.cloneElement(validateType(children), {...restProps})}
|
|
690
|
+
</View>
|
|
691
|
+
);
|
|
692
|
+
};
|
|
693
|
+
return <View style={styles.headerRightButton}>{renderAction()}</View>;
|
|
694
|
+
};
|
|
695
|
+
|
|
473
696
|
const styles = StyleSheet.create({
|
|
474
697
|
navigationButton: {
|
|
475
698
|
height: 28,
|
|
@@ -509,7 +732,6 @@ const styles = StyleSheet.create({
|
|
|
509
732
|
paddingRight: Spacing.M,
|
|
510
733
|
},
|
|
511
734
|
toolkitContainer: {
|
|
512
|
-
marginLeft: Spacing.S,
|
|
513
735
|
padding: Spacing.XS,
|
|
514
736
|
height: 28,
|
|
515
737
|
borderRadius: 14,
|
|
@@ -541,6 +763,17 @@ const styles = StyleSheet.create({
|
|
|
541
763
|
top: -Spacing.XS,
|
|
542
764
|
right: -Spacing.XS,
|
|
543
765
|
},
|
|
766
|
+
extendedHeader: {
|
|
767
|
+
aspectRatio: 1.75,
|
|
768
|
+
position: 'absolute',
|
|
769
|
+
width: '100%',
|
|
770
|
+
height: 210,
|
|
771
|
+
},
|
|
772
|
+
headerBox: {
|
|
773
|
+
width: '100%',
|
|
774
|
+
position: 'absolute',
|
|
775
|
+
overflow: 'hidden',
|
|
776
|
+
},
|
|
544
777
|
});
|
|
545
778
|
|
|
546
779
|
export {
|
|
@@ -548,8 +781,10 @@ export {
|
|
|
548
781
|
HeaderTitle,
|
|
549
782
|
HeaderLeft,
|
|
550
783
|
HeaderBackground,
|
|
551
|
-
HeaderRightAction,
|
|
552
784
|
HeaderToolkitAction,
|
|
553
785
|
HeaderCustom,
|
|
554
786
|
HeaderAnimated,
|
|
787
|
+
HeaderRight,
|
|
788
|
+
HeaderExtendHeader,
|
|
789
|
+
HeaderRightAction,
|
|
555
790
|
};
|
|
@@ -21,10 +21,10 @@ const ModalScreen: React.FC<any> = props => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const Modal: React.FC<ModalParams> = props => {
|
|
24
|
-
const {
|
|
24
|
+
const {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);
|
|
28
28
|
const params = {
|
|
29
29
|
...props.route.params,
|
|
30
30
|
navigation,
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import {NavigationProp} from '@react-navigation/native';
|
|
3
|
-
import {NavigationOptions
|
|
4
|
-
import {HeaderRightAction} from './index';
|
|
2
|
+
import {NavigationOptions} from './types';
|
|
5
3
|
import {getOptions} from './utils';
|
|
6
|
-
import {HeaderToolkitAction} from './Components';
|
|
7
4
|
|
|
8
5
|
class Navigation {
|
|
9
6
|
instance: NavigationProp<any>;
|
|
10
|
-
|
|
7
|
+
onHeaderRightChange?: (width: number) => void;
|
|
11
8
|
|
|
12
|
-
constructor(instance: any
|
|
9
|
+
constructor(instance: any) {
|
|
13
10
|
this.instance = instance;
|
|
14
|
-
this.theme = theme;
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
/**
|
|
@@ -19,16 +15,6 @@ class Navigation {
|
|
|
19
15
|
* @param params
|
|
20
16
|
*/
|
|
21
17
|
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
|
-
|
|
32
18
|
if (params.headerLeft) {
|
|
33
19
|
console.warn('headerLeft not allow override render by design system!');
|
|
34
20
|
delete params.headerLeft;
|
|
@@ -42,7 +28,7 @@ class Navigation {
|
|
|
42
28
|
* @param params
|
|
43
29
|
*/
|
|
44
30
|
setOptions = (params: NavigationOptions) => {
|
|
45
|
-
params = getOptions(this.filterParams(params), this
|
|
31
|
+
params = getOptions(this.filterParams(params), this);
|
|
46
32
|
this.instance.setOptions(params);
|
|
47
33
|
};
|
|
48
34
|
}
|
|
@@ -88,7 +88,7 @@ const EmptyScreen: React.FC = () => {
|
|
|
88
88
|
* @constructor
|
|
89
89
|
*/
|
|
90
90
|
const StackScreen: React.FC<ScreenParams> = props => {
|
|
91
|
-
const {
|
|
91
|
+
const {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,9 +104,8 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
104
104
|
});
|
|
105
105
|
const interaction = useRef<any>();
|
|
106
106
|
const context = useContext<any>(MiniAppContext);
|
|
107
|
-
|
|
108
107
|
const {screen: Component, options, initialParams} = props.route.params;
|
|
109
|
-
const navigation = new Navigation(props.navigation
|
|
108
|
+
const navigation = new Navigation(props.navigation);
|
|
110
109
|
const heightHeader = useHeaderHeight();
|
|
111
110
|
|
|
112
111
|
const data = {
|
|
@@ -124,9 +123,18 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
124
123
|
* set options for screen
|
|
125
124
|
*/
|
|
126
125
|
useLayoutEffect(() => {
|
|
126
|
+
let defaultOptions = {
|
|
127
|
+
headerRight: {
|
|
128
|
+
type: 'toolkit',
|
|
129
|
+
},
|
|
130
|
+
};
|
|
127
131
|
if (options) {
|
|
128
|
-
|
|
132
|
+
defaultOptions = {
|
|
133
|
+
...defaultOptions,
|
|
134
|
+
...options,
|
|
135
|
+
};
|
|
129
136
|
}
|
|
137
|
+
navigation.setOptions(defaultOptions);
|
|
130
138
|
navigator?.maxApi?.startTraceScreenLoad?.(screenName, (data: any) => {
|
|
131
139
|
tracked.current.traceIdLoad = data?.traceId;
|
|
132
140
|
});
|
|
@@ -147,7 +155,6 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
147
155
|
navigator?.showModal({screen: EmptyScreen});
|
|
148
156
|
}, 300);
|
|
149
157
|
}
|
|
150
|
-
|
|
151
158
|
navigator?.maxApi?.of?.({screenName});
|
|
152
159
|
tracked.current.timeoutLoad = setTimeout(() => {
|
|
153
160
|
onScreenLoad();
|
|
@@ -172,11 +179,13 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
172
179
|
if (timeLoad.current === 0) {
|
|
173
180
|
timeLoad.current = endTime.current - startTime.current;
|
|
174
181
|
}
|
|
182
|
+
|
|
175
183
|
context.autoTracking?.({
|
|
176
184
|
appId: context.appId,
|
|
177
185
|
code: context.code,
|
|
178
186
|
buildNumber: context.buildNumber,
|
|
179
187
|
screenName,
|
|
188
|
+
action: 'push',
|
|
180
189
|
componentName: 'Screen',
|
|
181
190
|
state: 'load',
|
|
182
191
|
duration: timeLoad.current,
|
|
@@ -186,14 +195,18 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
186
195
|
{value: timeLoad.current / 1000},
|
|
187
196
|
null
|
|
188
197
|
);
|
|
198
|
+
tracked.current.releaseLoad = true;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* debug
|
|
202
|
+
*/
|
|
189
203
|
navigator?.maxApi?.showToastDebug?.({
|
|
190
204
|
appId: `auto - ${context.appId}`,
|
|
191
205
|
message: `${screenName} screen_load_time ${timeLoad.current}`,
|
|
192
206
|
});
|
|
193
|
-
if (timeLoad.current
|
|
207
|
+
if (timeLoad.current <= 0 && context.enableAutoId) {
|
|
194
208
|
Alert.alert(screenName, "Can't get screen load time");
|
|
195
209
|
}
|
|
196
|
-
tracked.current.releaseLoad = true;
|
|
197
210
|
}
|
|
198
211
|
};
|
|
199
212
|
|
|
@@ -205,10 +218,7 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
205
218
|
if (timeLoad.current === 0) {
|
|
206
219
|
timeLoad.current = endTime.current - startTime.current;
|
|
207
220
|
}
|
|
208
|
-
if (timeInteraction.current === 0
|
|
209
|
-
if (context.enableAutoId) {
|
|
210
|
-
Alert.alert(screenName, "Can't get screen interaction time");
|
|
211
|
-
}
|
|
221
|
+
if (timeInteraction.current === 0) {
|
|
212
222
|
timeInteraction.current = timeLoad.current;
|
|
213
223
|
}
|
|
214
224
|
|
|
@@ -226,11 +236,18 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
226
236
|
{value: timeInteraction.current / 1000},
|
|
227
237
|
null
|
|
228
238
|
);
|
|
239
|
+
tracked.current.releaseInteraction = true;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* debug toast
|
|
243
|
+
*/
|
|
229
244
|
navigator?.maxApi?.showToastDebug?.({
|
|
230
245
|
appId: `auto - ${context.appId}`,
|
|
231
246
|
message: `${screenName} screen_interaction_time ${timeInteraction.current}`,
|
|
232
247
|
});
|
|
233
|
-
|
|
248
|
+
if (timeInteraction.current <= 0 && context.enableAutoId) {
|
|
249
|
+
Alert.alert(screenName, "Can't get screen interaction time");
|
|
250
|
+
}
|
|
234
251
|
}
|
|
235
252
|
};
|
|
236
253
|
|
package/Application/index.ts
CHANGED
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
HeaderAnimated,
|
|
6
6
|
HeaderBackground,
|
|
7
7
|
HeaderCustom,
|
|
8
|
-
HeaderRightAction,
|
|
9
8
|
HeaderTitle,
|
|
10
9
|
NavigationButton,
|
|
10
|
+
HeaderRightAction,
|
|
11
11
|
} from './Components';
|
|
12
12
|
import BottomTab from './BottomTab';
|
|
13
13
|
import {createContext} from 'react';
|
|
@@ -29,9 +29,9 @@ export {
|
|
|
29
29
|
Screen,
|
|
30
30
|
BottomTab,
|
|
31
31
|
NavigationButton,
|
|
32
|
+
HeaderRightAction,
|
|
32
33
|
HeaderTitle,
|
|
33
34
|
HeaderBackground,
|
|
34
|
-
HeaderRightAction,
|
|
35
35
|
HeaderCustom,
|
|
36
36
|
HeaderAnimated,
|
|
37
37
|
};
|
package/Application/types.ts
CHANGED
|
@@ -146,19 +146,29 @@ export type RuntimeToolType = {
|
|
|
146
146
|
key: string;
|
|
147
147
|
};
|
|
148
148
|
|
|
149
|
-
export interface NavigationOptions
|
|
149
|
+
export interface NavigationOptions
|
|
150
|
+
extends Omit<StackNavigationOptions, 'headerRight'> {
|
|
150
151
|
preventBack?: PopupNotifyProps;
|
|
151
152
|
onPressLeftHeader?: () => void;
|
|
152
153
|
surface?: boolean;
|
|
153
154
|
hiddenBack?: boolean;
|
|
154
155
|
customTitle?: TitleCustomProps;
|
|
155
|
-
|
|
156
|
-
pinnedTool?: PinnedToolType;
|
|
157
|
-
runtimeTools?: RuntimeToolType[];
|
|
158
|
-
preventClose?: PopupNotifyProps;
|
|
159
|
-
};
|
|
156
|
+
headerRight?: HeaderRightToolkit | HeaderRightActions | any;
|
|
160
157
|
}
|
|
161
158
|
|
|
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
|
+
|
|
162
172
|
export interface HeaderBackProps extends NavigationButtonProps {
|
|
163
173
|
preventBack?: PopupNotifyProps;
|
|
164
174
|
onPressLeftHeader?: () => void;
|