-
Notifications
You must be signed in to change notification settings - Fork 44
/
RootWrapper.js
114 lines (89 loc) · 2.95 KB
/
RootWrapper.js
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
102
103
104
105
106
107
108
109
110
111
112
113
114
/* @flow */
import React, { PropTypes, Component, Element as ReactElement } from 'react';
import { View } from 'react-native';
import invariant from 'invariant';
import warnOnce from './warningUtil';
import AddressBar from './AddressBar';
import { PAN_RESPONDER_BACK_ACTION } from './transitionRegistry';
import type { EnhancedNavigationState, Location } from './TypeDefinition';
import { ADDDRESS_BAR_HEIGHT, globalStyles as styles } from './styles';
const NAVIGATION_HEADER_BACK_BUTTON_BACK_ACTION = 'BackAction';
type Props = {
navigationTree: ReactElement,
navState: EnhancedNavigationState,
location: Location,
addressBar: boolean,
};
type Context = {
router: Object,
};
class RootWrapper extends Component<any, Props, any> {
static propTypes = {
navigationTree: PropTypes.element.isRequired,
navState: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
addressBar: PropTypes.bool,
};
static defaultProps = {
addressBar: false,
};
static contextTypes = {
router: PropTypes.object,
};
static childContextTypes = {
onNavigate: PropTypes.func,
};
getChildContext(): Object {
return {
onNavigate: this.handleNavigation,
};
}
componentWillMount(): void {
(this: any).handleNavigation = this.handleNavigation.bind(this);
}
props: Props;
context: Context;
handleNavigation(action: Object): boolean { // eslint-disable-line consistent-return
const { type } = action;
if (type === NAVIGATION_HEADER_BACK_BUTTON_BACK_ACTION ||
type === PAN_RESPONDER_BACK_ACTION) {
warnOnce(
false,
'Using <NavigationHeader /> with the default `renderLeftComponent` prop that uses' +
'<NavigationHeaderBackButton />. Instead, you should override it with a custom' +
'`renderLeftComponent` that uses <Pop /> or `context.router.pop()`.'
);
const didPop = this.context.router.pop();
return didPop;
}
invariant(
false,
'onNavigate is not supported. Use <Link /> or context.router.push() instead.'
);
}
renderNavigation(navigationState: EnhancedNavigationState): ?ReactElement {
const { navigationTree } = this.props;
if (!navigationState) {
return null;
}
return React.cloneElement(navigationTree, { _navigationState: navigationState });
}
render(): ReactElement {
const { navState, addressBar: isShown, location } = this.props;
// TODO react-native does not accept `-reverse` values for `flex-direction`. We need to render
// <AddressBar /> after navigational components to keep it on top. See react-native/pull/6473
let rootStyles;
if (isShown) {
rootStyles = [styles.wrapper, { marginTop: ADDDRESS_BAR_HEIGHT }];
} else {
rootStyles = styles.wrapper;
}
return (
<View style={rootStyles}>
{this.renderNavigation(navState)}
<AddressBar show={isShown} location={location} />
</View>
);
}
}
export default RootWrapper;