Skip to content

Commit c1a762a

Browse files
committed
Navigation moved to extension.
StandardDelegate uses react-native-deprecated-components Navigator.
1 parent 270c0ac commit c1a762a

20 files changed

+4435
-0
lines changed

extensions/navigation/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist
2+
node_modules
3+
.DS_Store

extensions/navigation/README.md

+233
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
d: components/navigator
2+
title: Navigator
3+
layout: docs
4+
category: Components
5+
permalink: docs/components/navigator.html
6+
next: components/picker
7+
---
8+
9+
This component provides a way for the app to present a virtual stack of "cards", allowing the user to push or pop those cards onto the stack in an animated manner. The caller can control the animation type and direction.
10+
11+
When a new card is presented, the Navitator calls the renderScene method, allowing the caller to render the contents. Cards are identified by "routes", which contain a unique ID and configuration parameters that control the behavior of the transition.
12+
13+
When a Navigator is first mounted, the stack is empty. The caller must wait for the mount to complete, then specify the list of routes to present.
14+
15+
The current implementation of Navitator on React Native makes use of the soon-to-be-deprecated "Navigator Experimental". We will look at moving away from this implementation to the now-recommended "react-navigation" in the near future. Some of the more advanced interfaces may need to change. These are listed at the end of this article. Use these with caution.
16+
17+
## Types
18+
``` javascript
19+
// Specifies the behavior when transitioning from one
20+
// card to another within the stack.
21+
enum NavigatorSceneConfigType {
22+
FloatFromRight,
23+
FloatFromLeft,
24+
FloatFromBottom,
25+
Fade,
26+
FadeWithSlide
27+
}
28+
29+
// Provides information about a card and how it should
30+
// be presented when pushed onto the stack or popped
31+
// off the stack.
32+
interface NavigatorRoute {
33+
// Uniquely identifies the card
34+
routeId: number;
35+
36+
// Animation parameter
37+
sceneConfigType: NavigatorSceneConfigType;
38+
39+
// Optional gesture response distance override;
40+
// 0 is equivalent to disabling gestures;
41+
// works only on React Native platforms
42+
gestureResponseDistance?: number;
43+
44+
// Optional custom scene config;
45+
// works only on React Native platforms
46+
customSceneConfig?: CustomNavigatorSceneConfig;
47+
}
48+
```
49+
50+
## Props
51+
``` javascript
52+
// Style to apply to the card
53+
cardStyle: ViewStyleRuleSet = undefined;
54+
55+
// Called to render the specified scene
56+
renderScene: (route: NavigatorRoute) => JSX.Element = undefined;
57+
58+
// Called when a transition between cards is complete
59+
transitionCompleted: () => void = undefined;
60+
```
61+
62+
## Methods
63+
``` javascript
64+
// Returns the current list of routes
65+
getCurrentRoutes(): Types.NavigatorRoute[];
66+
67+
// Replaces the current list of routes with a new list
68+
immediatelyResetRouteStack(
69+
nextRouteStack: Types.NavigatorRoute[]): void;
70+
71+
// Pops the top route off the stack
72+
pop(): void;
73+
74+
// Pops zero or more routes off the top of the stack until
75+
// the specified route is top-most
76+
popToRoute(route: Types.NavigatorRoute): void;
77+
78+
// Pops all routes off the stack except for the last
79+
// remaining item in the stack
80+
popToTop(): void;
81+
82+
// Push a new route onto the stack
83+
push(route: Types.NavigatorRoute): void;
84+
85+
// Replaces the top-most route with a new route
86+
replace(route: Types.NavigatorRoute): void;
87+
88+
// Replaces an existing route (identified by index) with
89+
// a new route
90+
replaceAtIndex(route: Types.NavigatorRoute, index: number): void;
91+
92+
// Replaces the next-to-top-most route with a new route
93+
replacePrevious(route: Types.NavigatorRoute): void;
94+
```
95+
96+
## Sample Usage
97+
98+
This sample demonstrates how an app can use Navigator to present a two-card stack, allowing the user to navigate between them. It omits some details for brevity. For a full working example, check out the hello-world sample app.
99+
100+
``` javascript
101+
enum NavigationRouteId {
102+
MainPanel,
103+
SecondPanel
104+
};
105+
106+
class App extends RX.Component<null, null> {
107+
private _navigator: RX.Navigator;
108+
109+
componentDidMount() {
110+
// Now that the app is mounted, specify the initial
111+
// navigator route.
112+
this._navigator.immediatelyResetRouteStack([{
113+
routeId: NavigationRouteId.MainPanel,
114+
sceneConfigType: RX.Types.NavigatorSceneConfigType.Fade
115+
}]);
116+
}
117+
118+
render() {
119+
return (
120+
<RX.Navigator
121+
ref={ this._onNavigatorRef }
122+
renderScene={ this._renderScene }
123+
/>
124+
);
125+
}
126+
127+
private _onNavigatorRef = (naviator: RX.Navigator) => {
128+
// Stash away a reference to the mounted navigator
129+
this._navigator = navigator;
130+
}
131+
132+
private _renderScene = (route: NavigatorRoute) => {
133+
switch (navigatorRoute.routeId) {
134+
case NavigationRouteId.MainPanel:
135+
return (
136+
<MainPanel
137+
onPressNavigate={ this._onPressNavigate }
138+
/>
139+
);
140+
141+
case NavigationRouteId.SecondPanel:
142+
return (
143+
<SecondPanel
144+
onNavigateBack={ this._onPressBack }
145+
/>
146+
);
147+
}
148+
149+
return null;
150+
}
151+
152+
// Called when the user presses a button on the MainPanel
153+
// to navigate to the SecondPanel.
154+
private _onPressNavigate = () => {
155+
this._navigator.push({
156+
routeId: NavigationRouteId.SecondPanel,
157+
sceneConfigType:
158+
RX.Types.NavigatorSceneConfigType.FloatFromRight,
159+
customSceneConfig: {
160+
hideShadow: true
161+
}
162+
});
163+
}
164+
165+
// Called when the user presses a back button on the
166+
// SecondPanel to navigate back to the MainPanel.
167+
private _onPressBack = () => {
168+
this._navigator.pop();
169+
}
170+
}
171+
```
172+
173+
174+
## Experimental Types
175+
176+
These types apply only to React Native platforms, and they currently rely on the soon-to-be-deprecated "Experimental Navigator". Some or all of these types may be deprecated in the near future, so use with caution.
177+
178+
``` javascript
179+
// Additional options that affect card transitions
180+
type CustomNavigatorSceneConfig = {
181+
// Optional transition styles
182+
transitionStyle?: (sceneIndex: number,
183+
sceneDimensions: Dimensions) =>
184+
NavigationTransitionStyleConfig;
185+
186+
// Optional overrides for duration, easing, and timing
187+
transitionSpec?: NavigationTransitionSpec;
188+
189+
// Optional cardStyle override
190+
cardStyle?: ViewStyleRuleSet;
191+
192+
// Optionally hide drop shadow
193+
hideShadow?: boolean;
194+
195+
// Optionally flip the visual order of the last two scenes
196+
presentBelowPrevious?: boolean;
197+
};
198+
199+
// Parameters to control transition animations
200+
type NavigationTransitionSpec = {
201+
duration?: number;
202+
easing?: Animated.EasingFunction;
203+
};
204+
205+
// Parameters to control transition appearance
206+
type NavigationTransitionStyleConfig = {
207+
// By default, input range is defined as [index - 1, index, index + 1];
208+
// Input and output ranges must contain the same number of elements
209+
inputRange?: number[];
210+
opacityOutput: number | number[];
211+
scaleOutput: number | number[];
212+
translateXOutput: number | number[];
213+
translateYOutput: number | number[];
214+
};
215+
```
216+
217+
## Experimental Props
218+
219+
These props apply only to React Native platforms, and they currently rely on the soon-to-be-deprecated "Experimental Navigator". Some or all of these props may be deprecated in the near future, so use with caution.
220+
221+
``` javascript
222+
// Called after the user swipes back in the stack and the transition
223+
// is complete
224+
navigateBackCompleted: () => void;
225+
226+
// Called when a transition begins; works only
227+
// on native
228+
transitionStarted: (progress?: RX.AnimatedValue,
229+
toRouteId?: string, fromRouteId?: string,
230+
toIndex?: number, fromIndex?: number) => void = undefined;
231+
```
232+
233+
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
module.exports = require('./dist/native-common/Navigator');

extensions/navigation/index.ios.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
module.exports = require('./dist/native-common/Navigator');

extensions/navigation/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
'use strict';
2+
3+
// Export web by default. Other platforms have custom index.[platform].js files
4+
module.exports = require('./dist/web/Navigator');
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
module.exports = require('./dist/native-common/Navigator');

extensions/navigation/package.json

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "reactxp-navigation",
3+
"version": "1.0.0",
4+
"description": "ReactXP cross-platform navigation framework",
5+
"scripts": {
6+
"build": "tsc",
7+
"tslint": "tslint --project tsconfig.json -r tslint.json --fix || true"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/Microsoft/reactxp/tree/master/extensions/navigation"
12+
},
13+
"keywords": [
14+
"react-native",
15+
"reactxp",
16+
"react"
17+
],
18+
"dependencies": {
19+
"@types/lodash": "4.14.62",
20+
"@types/node": "6.0.65",
21+
"assert": "^1.3.0",
22+
"lodash": "4.17.1",
23+
"rebound": "^0.0.13",
24+
"react-native-deprecated-custom-components": "0.1.1",
25+
"reactxp-experimental-navigation": "1.0.4"
26+
},
27+
"peerDependencies": {
28+
"react": "^0.14.8",
29+
"react-dom": "^15.4.1",
30+
"react-native": "^0.42.0"
31+
},
32+
"devDependencies": {
33+
"reactxp": "^0.42.0-rc.25",
34+
"typescript": "2.4.1",
35+
"tslint": "^5.0.0"
36+
},
37+
"author": "Sergei Dryganets",
38+
"license": "MIT",
39+
"types": "dist/web/Navigator.d.ts"
40+
}

0 commit comments

Comments
 (0)