/
createStackNavigator.tsx
101 lines (94 loc) · 2.51 KB
/
createStackNavigator.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import * as React from 'react';
import { Platform } from 'react-native';
import {
useNavigationBuilder,
createNavigatorFactory,
DefaultNavigatorOptions,
EventArg,
StackRouter,
StackRouterOptions,
StackNavigationState,
StackActions,
ParamListBase,
StackActionHelpers,
} from '@react-navigation/native';
import StackView from '../views/Stack/StackView';
import type {
StackNavigationConfig,
StackNavigationOptions,
StackNavigationEventMap,
} from '../types';
type Props = DefaultNavigatorOptions<StackNavigationOptions> &
StackRouterOptions &
StackNavigationConfig;
function StackNavigator({
initialRouteName,
children,
screenOptions,
...rest
}: Props) {
const defaultOptions = {
gestureEnabled: Platform.OS === 'ios',
animationEnabled:
Platform.OS !== 'web' &&
Platform.OS !== 'windows' &&
Platform.OS !== 'macos',
};
const { state, descriptors, navigation } = useNavigationBuilder<
StackNavigationState<ParamListBase>,
StackRouterOptions,
StackActionHelpers<ParamListBase>,
StackNavigationOptions,
StackNavigationEventMap
>(StackRouter, {
initialRouteName,
children,
screenOptions:
typeof screenOptions === 'function'
? (...args) => ({
...defaultOptions,
...screenOptions(...args),
})
: {
...defaultOptions,
...screenOptions,
},
});
React.useEffect(
() =>
navigation.addListener?.('tabPress', (e) => {
const isFocused = navigation.isFocused();
// Run the operation in the next frame so we're sure all listeners have been run
// This is necessary to know if preventDefault() has been called
requestAnimationFrame(() => {
if (
state.index > 0 &&
isFocused &&
!(e as EventArg<'tabPress', true>).defaultPrevented
) {
// When user taps on already focused tab and we're inside the tab,
// reset the stack to replicate native behaviour
navigation.dispatch({
...StackActions.popToTop(),
target: state.key,
});
}
});
}),
[navigation, state.index, state.key]
);
return (
<StackView
{...rest}
state={state}
descriptors={descriptors}
navigation={navigation}
/>
);
}
export default createNavigatorFactory<
StackNavigationState<ParamListBase>,
StackNavigationOptions,
StackNavigationEventMap,
typeof StackNavigator
>(StackNavigator);