@momo-kits/foundation 0.92.26-beta.22 → 0.92.26-beta.24
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 -235
- package/Application/ModalScreen.tsx +2 -2
- package/Application/Navigation.ts +18 -4
- package/Application/StackScreen.tsx +13 -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 -171
- 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,15 +1,14 @@
|
|
|
1
1
|
import React, {
|
|
2
|
+
Fragment,
|
|
2
3
|
useCallback,
|
|
3
4
|
useContext,
|
|
4
5
|
useEffect,
|
|
5
|
-
useRef,
|
|
6
6
|
useState,
|
|
7
7
|
} from 'react';
|
|
8
8
|
import {
|
|
9
9
|
Animated,
|
|
10
10
|
BackHandler,
|
|
11
11
|
DeviceEventEmitter,
|
|
12
|
-
Dimensions,
|
|
13
12
|
StatusBar,
|
|
14
13
|
StyleSheet,
|
|
15
14
|
TouchableOpacity,
|
|
@@ -30,17 +29,7 @@ import {scaleSize, Text} from '../Text';
|
|
|
30
29
|
import {Icon} from '../Icon';
|
|
31
30
|
import {PopupNotify} from '../Popup';
|
|
32
31
|
import {Badge, BadgeDot} from '../Badge';
|
|
33
|
-
import {HeaderType} from '../Layout/types';
|
|
34
|
-
import Navigation from './Navigation';
|
|
35
|
-
import {InputSearch, InputSearchProps} from '../Input';
|
|
36
32
|
|
|
37
|
-
const SCREEN_PADDING = 12;
|
|
38
|
-
const BACK_WIDTH = 28;
|
|
39
|
-
const {width: screenWidth} = Dimensions.get('window');
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* default navigation button used header nav
|
|
43
|
-
*/
|
|
44
33
|
const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
45
34
|
icon,
|
|
46
35
|
tintColor,
|
|
@@ -92,18 +81,13 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
|
92
81
|
);
|
|
93
82
|
};
|
|
94
83
|
|
|
95
|
-
/**
|
|
96
|
-
* default header title used for nav
|
|
97
|
-
*/
|
|
98
84
|
const HeaderTitle: React.FC<any> = props => {
|
|
99
85
|
const {theme} = useContext(ApplicationContext);
|
|
100
|
-
const opacity = props.animatedValue?.interpolate(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
);
|
|
86
|
+
const opacity = props.animatedValue?.interpolate({
|
|
87
|
+
inputRange: [0, 200],
|
|
88
|
+
outputRange: [0, 1],
|
|
89
|
+
extrapolate: 'clamp',
|
|
90
|
+
});
|
|
107
91
|
|
|
108
92
|
return (
|
|
109
93
|
<Animated.Text
|
|
@@ -117,9 +101,6 @@ const HeaderTitle: React.FC<any> = props => {
|
|
|
117
101
|
);
|
|
118
102
|
};
|
|
119
103
|
|
|
120
|
-
/**
|
|
121
|
-
* default header left used for nav
|
|
122
|
-
*/
|
|
123
104
|
const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
124
105
|
tintColor,
|
|
125
106
|
preventBack,
|
|
@@ -132,7 +113,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
132
113
|
useEffect(() => {
|
|
133
114
|
const backHandler = BackHandler.addEventListener(
|
|
134
115
|
'hardwareBackPress',
|
|
135
|
-
goBackSafe
|
|
116
|
+
goBackSafe,
|
|
136
117
|
);
|
|
137
118
|
|
|
138
119
|
return () => backHandler.remove();
|
|
@@ -187,7 +168,6 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
187
168
|
}
|
|
188
169
|
return true;
|
|
189
170
|
};
|
|
190
|
-
|
|
191
171
|
return (
|
|
192
172
|
<View style={styles.headerLeft}>
|
|
193
173
|
<NavigationButton
|
|
@@ -201,9 +181,6 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
201
181
|
);
|
|
202
182
|
};
|
|
203
183
|
|
|
204
|
-
/**
|
|
205
|
-
* header background for default
|
|
206
|
-
*/
|
|
207
184
|
const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
208
185
|
image,
|
|
209
186
|
animatedValue,
|
|
@@ -252,10 +229,6 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
252
229
|
);
|
|
253
230
|
};
|
|
254
231
|
|
|
255
|
-
/**
|
|
256
|
-
* Header custom with image, title, subtitle
|
|
257
|
-
* @constructor
|
|
258
|
-
*/
|
|
259
232
|
const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
260
233
|
title,
|
|
261
234
|
subTitle,
|
|
@@ -290,42 +263,37 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
|
290
263
|
return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
|
|
291
264
|
};
|
|
292
265
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
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
|
+
);
|
|
301
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
|
+
|
|
302
288
|
return (
|
|
303
|
-
<View style={styles.
|
|
304
|
-
{
|
|
305
|
-
return (
|
|
306
|
-
<View
|
|
307
|
-
key={`HeaderRightAction ${index}`}
|
|
308
|
-
style={{
|
|
309
|
-
marginLeft: index !== 0 ? Spacing.S : 0,
|
|
310
|
-
}}>
|
|
311
|
-
<NavigationButton {...item} tintColor={props?.tintColor} />
|
|
312
|
-
</View>
|
|
313
|
-
);
|
|
314
|
-
})}
|
|
289
|
+
<View style={styles.headerButton}>
|
|
290
|
+
{React.cloneElement(validateType(children), {...restProps})}
|
|
315
291
|
</View>
|
|
316
292
|
);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return (
|
|
320
|
-
<View style={styles.headerRightButton} onLayout={onLayout}>
|
|
321
|
-
{children ?? <HeaderToolkitAction {...props} />}
|
|
322
|
-
</View>
|
|
323
|
-
);
|
|
293
|
+
};
|
|
294
|
+
return <View style={styles.headerRightButton}>{renderAction()}</View>;
|
|
324
295
|
};
|
|
325
296
|
|
|
326
|
-
/**
|
|
327
|
-
* Header toolkit action
|
|
328
|
-
*/
|
|
329
297
|
const HeaderToolkitAction: React.FC<any> = ({
|
|
330
298
|
tintColor,
|
|
331
299
|
pinnedTool,
|
|
@@ -359,7 +327,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
359
327
|
(config: any) => {
|
|
360
328
|
navigator.toolkitConfig = config;
|
|
361
329
|
setToolConfig(navigator?.toolkitConfig);
|
|
362
|
-
}
|
|
330
|
+
},
|
|
363
331
|
);
|
|
364
332
|
};
|
|
365
333
|
|
|
@@ -372,7 +340,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
372
340
|
const {item} = res;
|
|
373
341
|
navigator?.toolkitCallback?.(item);
|
|
374
342
|
getToolkitConfig();
|
|
375
|
-
}
|
|
343
|
+
},
|
|
376
344
|
);
|
|
377
345
|
};
|
|
378
346
|
|
|
@@ -389,7 +357,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
389
357
|
navigator?.maxApi?.dispatchFunction?.(
|
|
390
358
|
'dismiss',
|
|
391
359
|
undefined,
|
|
392
|
-
undefined
|
|
360
|
+
undefined,
|
|
393
361
|
);
|
|
394
362
|
},
|
|
395
363
|
}}
|
|
@@ -420,7 +388,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
420
388
|
[pinTool?.key],
|
|
421
389
|
() => {
|
|
422
390
|
getToolkitConfig();
|
|
423
|
-
}
|
|
391
|
+
},
|
|
424
392
|
);
|
|
425
393
|
navigator?.toolkitCallback?.(pinTool.key);
|
|
426
394
|
}}
|
|
@@ -429,7 +397,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
429
397
|
};
|
|
430
398
|
if (toolConfig) {
|
|
431
399
|
return (
|
|
432
|
-
<View style={
|
|
400
|
+
<View style={styles.headerRightButton}>
|
|
433
401
|
{renderPinnedTool()}
|
|
434
402
|
<View
|
|
435
403
|
style={[
|
|
@@ -437,7 +405,6 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
437
405
|
{
|
|
438
406
|
backgroundColor: backgroundColor ?? '#00000066',
|
|
439
407
|
borderWidth: backgroundColor ? 0.5 : 0,
|
|
440
|
-
marginLeft: renderPinnedTool() ? Spacing.S : 0,
|
|
441
408
|
},
|
|
442
409
|
]}>
|
|
443
410
|
<TouchableOpacity
|
|
@@ -463,9 +430,6 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
463
430
|
return <View />;
|
|
464
431
|
};
|
|
465
432
|
|
|
466
|
-
/**
|
|
467
|
-
* default header banner for header animated
|
|
468
|
-
*/
|
|
469
433
|
const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
470
434
|
animatedValue,
|
|
471
435
|
image,
|
|
@@ -506,155 +470,6 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
|
506
470
|
);
|
|
507
471
|
};
|
|
508
472
|
|
|
509
|
-
/**
|
|
510
|
-
* Header extended with background image
|
|
511
|
-
* @constructor
|
|
512
|
-
*/
|
|
513
|
-
const HeaderExtendHeader: React.FC<{
|
|
514
|
-
headerType?: HeaderType;
|
|
515
|
-
animatedValue: Animated.Value;
|
|
516
|
-
heightHeader: number;
|
|
517
|
-
inputSearchProps?: InputSearchProps;
|
|
518
|
-
navigation?: Navigation;
|
|
519
|
-
}> = ({
|
|
520
|
-
headerType = 'default',
|
|
521
|
-
animatedValue,
|
|
522
|
-
heightHeader,
|
|
523
|
-
inputSearchProps,
|
|
524
|
-
navigation,
|
|
525
|
-
}) => {
|
|
526
|
-
const {theme} = useContext(ApplicationContext);
|
|
527
|
-
const [rightSpace, setRightSpace] = useState(0);
|
|
528
|
-
const animated = useRef(new Animated.Value(0));
|
|
529
|
-
|
|
530
|
-
useEffect(() => {
|
|
531
|
-
const listener = animatedValue.addListener(({value}) => {
|
|
532
|
-
animated.current.setValue(value);
|
|
533
|
-
});
|
|
534
|
-
return () => {
|
|
535
|
-
animatedValue?.removeListener(listener);
|
|
536
|
-
};
|
|
537
|
-
}, []);
|
|
538
|
-
|
|
539
|
-
const height = animated.current.interpolate({
|
|
540
|
-
inputRange: [0, 100],
|
|
541
|
-
outputRange: [heightHeader + 52, heightHeader],
|
|
542
|
-
extrapolate: 'clamp',
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
const translateX = animated.current.interpolate({
|
|
546
|
-
inputRange: [0, 100],
|
|
547
|
-
outputRange: [SCREEN_PADDING, BACK_WIDTH + SCREEN_PADDING * 2],
|
|
548
|
-
extrapolate: 'clamp',
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
navigation!.onHeaderRightChange = (width: number) => {
|
|
552
|
-
setRightSpace(width);
|
|
553
|
-
};
|
|
554
|
-
|
|
555
|
-
const renderInputView = (hasColorBG: boolean = false) => {
|
|
556
|
-
return (
|
|
557
|
-
<Animated.View
|
|
558
|
-
style={{
|
|
559
|
-
justifyContent: 'flex-end',
|
|
560
|
-
height,
|
|
561
|
-
}}>
|
|
562
|
-
<Animated.View
|
|
563
|
-
style={{
|
|
564
|
-
transform: [{translateX}],
|
|
565
|
-
marginVertical: Spacing.S,
|
|
566
|
-
width: animated.current.interpolate({
|
|
567
|
-
inputRange: [0, 100],
|
|
568
|
-
outputRange: [
|
|
569
|
-
screenWidth - SCREEN_PADDING * 2,
|
|
570
|
-
screenWidth - SCREEN_PADDING * 3 - BACK_WIDTH - rightSpace,
|
|
571
|
-
],
|
|
572
|
-
extrapolate: 'clamp',
|
|
573
|
-
}),
|
|
574
|
-
}}>
|
|
575
|
-
<InputSearch
|
|
576
|
-
{...inputSearchProps}
|
|
577
|
-
hasColorBG={hasColorBG}
|
|
578
|
-
showButtonText={false}
|
|
579
|
-
/>
|
|
580
|
-
</Animated.View>
|
|
581
|
-
</Animated.View>
|
|
582
|
-
);
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
if (inputSearchProps) {
|
|
586
|
-
if (headerType === 'surface') {
|
|
587
|
-
return (
|
|
588
|
-
<>
|
|
589
|
-
<Animated.View
|
|
590
|
-
style={[
|
|
591
|
-
styles.headerBox,
|
|
592
|
-
{
|
|
593
|
-
backgroundColor: theme.colors.background.surface,
|
|
594
|
-
borderBottomWidth: 1,
|
|
595
|
-
borderColor: theme.colors.border.default,
|
|
596
|
-
height,
|
|
597
|
-
},
|
|
598
|
-
]}
|
|
599
|
-
/>
|
|
600
|
-
{renderInputView(true)}
|
|
601
|
-
</>
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (headerType === 'extended') {
|
|
606
|
-
return (
|
|
607
|
-
<>
|
|
608
|
-
<Animated.View
|
|
609
|
-
style={[
|
|
610
|
-
styles.headerBox,
|
|
611
|
-
{
|
|
612
|
-
height,
|
|
613
|
-
},
|
|
614
|
-
]}>
|
|
615
|
-
<Image
|
|
616
|
-
source={{
|
|
617
|
-
uri: theme.assets?.headerBackground,
|
|
618
|
-
}}
|
|
619
|
-
style={styles.headerBackground}
|
|
620
|
-
/>
|
|
621
|
-
</Animated.View>
|
|
622
|
-
{renderInputView()}
|
|
623
|
-
</>
|
|
624
|
-
);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
return (
|
|
628
|
-
<>
|
|
629
|
-
<View style={[styles.headerBox, {height: heightHeader}]}>
|
|
630
|
-
<Image
|
|
631
|
-
source={{
|
|
632
|
-
uri: theme.assets?.headerBackground,
|
|
633
|
-
}}
|
|
634
|
-
style={styles.headerBackground}
|
|
635
|
-
/>
|
|
636
|
-
</View>
|
|
637
|
-
{renderInputView()}
|
|
638
|
-
</>
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
if (headerType === 'extended') {
|
|
643
|
-
return (
|
|
644
|
-
<View style={{minHeight: heightHeader}}>
|
|
645
|
-
<Image
|
|
646
|
-
source={{
|
|
647
|
-
uri: theme.assets?.headerBackground,
|
|
648
|
-
}}
|
|
649
|
-
style={styles.extendedHeader}
|
|
650
|
-
/>
|
|
651
|
-
</View>
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
return <View />;
|
|
656
|
-
};
|
|
657
|
-
|
|
658
473
|
const styles = StyleSheet.create({
|
|
659
474
|
navigationButton: {
|
|
660
475
|
height: 28,
|
|
@@ -694,6 +509,7 @@ const styles = StyleSheet.create({
|
|
|
694
509
|
paddingRight: Spacing.M,
|
|
695
510
|
},
|
|
696
511
|
toolkitContainer: {
|
|
512
|
+
marginLeft: Spacing.S,
|
|
697
513
|
padding: Spacing.XS,
|
|
698
514
|
height: 28,
|
|
699
515
|
borderRadius: 14,
|
|
@@ -725,17 +541,6 @@ const styles = StyleSheet.create({
|
|
|
725
541
|
top: -Spacing.XS,
|
|
726
542
|
right: -Spacing.XS,
|
|
727
543
|
},
|
|
728
|
-
extendedHeader: {
|
|
729
|
-
aspectRatio: 1.75,
|
|
730
|
-
position: 'absolute',
|
|
731
|
-
width: '100%',
|
|
732
|
-
height: 210,
|
|
733
|
-
},
|
|
734
|
-
headerBox: {
|
|
735
|
-
width: '100%',
|
|
736
|
-
position: 'absolute',
|
|
737
|
-
overflow: 'hidden',
|
|
738
|
-
},
|
|
739
544
|
});
|
|
740
545
|
|
|
741
546
|
export {
|
|
@@ -743,9 +548,8 @@ export {
|
|
|
743
548
|
HeaderTitle,
|
|
744
549
|
HeaderLeft,
|
|
745
550
|
HeaderBackground,
|
|
551
|
+
HeaderRightAction,
|
|
746
552
|
HeaderToolkitAction,
|
|
747
553
|
HeaderCustom,
|
|
748
554
|
HeaderAnimated,
|
|
749
|
-
HeaderRight,
|
|
750
|
-
HeaderExtendHeader,
|
|
751
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,7 +157,6 @@ 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) {
|
|
169
161
|
context.autoTracking?.({
|
|
170
162
|
appId: context.appId,
|
|
@@ -179,6 +171,9 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
179
171
|
appId: `auto - ${context.appId}`,
|
|
180
172
|
message: `${screenName} screen_load_time ${timeLoad.current}`,
|
|
181
173
|
});
|
|
174
|
+
if (timeLoad.current === 0) {
|
|
175
|
+
Alert.alert(screenName, "Can't get screen load time");
|
|
176
|
+
}
|
|
182
177
|
tracked.current.releaseLoad = true;
|
|
183
178
|
}
|
|
184
179
|
};
|
|
@@ -187,7 +182,6 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
187
182
|
* tracking for screen load
|
|
188
183
|
*/
|
|
189
184
|
const onScreenInteraction = () => {
|
|
190
|
-
clearTimeout(tracked.current.timeoutInteraction);
|
|
191
185
|
if (!tracked.current?.releaseInteraction) {
|
|
192
186
|
context.autoTracking?.({
|
|
193
187
|
appId: context.appId,
|
|
@@ -203,6 +197,9 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
203
197
|
appId: `auto - ${context.appId}`,
|
|
204
198
|
message: `${screenName} screen_interaction_time ${timeInteraction.current}`,
|
|
205
199
|
});
|
|
200
|
+
if (timeInteraction.current - timeLoad.current <= 0) {
|
|
201
|
+
Alert.alert(screenName, "Can't get screen interaction time");
|
|
202
|
+
}
|
|
206
203
|
tracked.current.releaseInteraction = true;
|
|
207
204
|
}
|
|
208
205
|
};
|
|
@@ -212,12 +209,12 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
212
209
|
value={{
|
|
213
210
|
screenName,
|
|
214
211
|
onElementLoad: () => {
|
|
212
|
+
clearTimeout(timeoutLoad.current);
|
|
215
213
|
endTime.current = Date.now();
|
|
216
214
|
interaction.current?.cancel?.();
|
|
217
215
|
interaction.current = InteractionManager.runAfterInteractions(() => {
|
|
218
216
|
timeInteraction.current = Date.now() - startTime.current;
|
|
219
217
|
});
|
|
220
|
-
clearTimeout(timeoutLoad.current);
|
|
221
218
|
timeoutLoad.current = setTimeout(() => {
|
|
222
219
|
if (timeLoad.current === 0) {
|
|
223
220
|
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;
|