diff --git a/Examples/UIExplorer/NavigationExperimental/NavigationCardStackExample.js b/Examples/UIExplorer/NavigationExperimental/NavigationCardStackExample.js
new file mode 100644
index 000000000..2063e7615
--- /dev/null
+++ b/Examples/UIExplorer/NavigationExperimental/NavigationCardStackExample.js
@@ -0,0 +1,114 @@
+/**
+ * The examples provided by Facebook are for non-commercial testing and
+ * evaluation purposes only.
+ *
+ * Facebook reserves all rights not expressly granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
+ * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+'use strict';
+
+const NavigationExampleRow = require('./NavigationExampleRow');
+const React = require('react-native');
+
+const {
+ NavigationExperimental,
+ StyleSheet,
+ ScrollView,
+} = React;
+
+const NavigationCardStack = NavigationExperimental.CardStack;
+const NavigationStateUtils = NavigationExperimental.StateUtils;
+
+class NavigationCardStackExample extends React.Component {
+
+ constructor(props, context) {
+ super(props, context);
+ this.state = this._getInitialState();
+ this._renderScene = this._renderScene.bind(this);
+ this._push = this._push.bind(this);
+ this._pop = this._pop.bind(this);
+ }
+
+ render() {
+ return (
+
+ );
+ }
+
+ _getInitialState() {
+ const route = {key: 'First Route'};
+ const navigationState = {
+ index: 0,
+ children: [route],
+ };
+ return {
+ navigationState,
+ };
+ }
+
+ _push() {
+ const state = this.state.navigationState;
+ const nextRoute = {key: 'Route ' + (state.index + 1)};
+ const nextState = NavigationStateUtils.push(
+ state,
+ nextRoute,
+ );
+ this.setState({
+ navigationState: nextState,
+ });
+ }
+
+ _pop() {
+ const state = this.state.navigationState;
+ const nextState = state.index > 0 ?
+ NavigationStateUtils.pop(state) :
+ state;
+
+ this.setState({
+ navigationState: nextState,
+ });
+ }
+
+ _renderScene(navigationState, index, position, layout) {
+ return (
+
+
+
+
+
+
+ );
+ }
+}
+
+const styles = StyleSheet.create({
+ main: {
+ flex: 1,
+ },
+ scrollView: {
+ marginTop: 64
+ },
+});
+
+module.exports = NavigationCardStackExample;
diff --git a/Examples/UIExplorer/NavigationExperimental/NavigationExperimentalExample.js b/Examples/UIExplorer/NavigationExperimental/NavigationExperimentalExample.js
index 0a813410d..f15b9926a 100644
--- a/Examples/UIExplorer/NavigationExperimental/NavigationExperimentalExample.js
+++ b/Examples/UIExplorer/NavigationExperimental/NavigationExperimentalExample.js
@@ -32,6 +32,7 @@ var EXAMPLES = {
'Basic': require('./NavigationBasicExample'),
'Animated Card Stack': require('./NavigationAnimatedExample'),
'Composition': require('./NavigationCompositionExample'),
+ 'Card Stack Example': require('./NavigationCardStackExample'),
'Tic Tac Toe': require('./NavigationTicTacToeExample'),
};
diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js b/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js
new file mode 100644
index 000000000..f2cabdda8
--- /dev/null
+++ b/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2015, Facebook, Inc. All rights reserved.
+ *
+ * Facebook, Inc. ("Facebook") owns all right, title and interest, including
+ * all intellectual property and other proprietary rights, in and to the React
+ * Native CustomComponents software (the "Software"). Subject to your
+ * compliance with these terms, you are hereby granted a non-exclusive,
+ * worldwide, royalty-free copyright license to (1) use and copy the Software;
+ * and (2) reproduce and distribute the Software as part of your own software
+ * ("Your Software"). Facebook reserves all rights not expressly granted to
+ * you in this license agreement.
+ *
+ * THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED.
+ * IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR
+ * EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @providesModule NavigationCardStack
+ * @flow
+ */
+'use strict';
+
+const NavigationAnimatedView = require('NavigationAnimatedView');
+const NavigationCard = require('NavigationCard');
+const NavigationContainer = require('NavigationContainer');
+const React = require('React');
+const StyleSheet = require('StyleSheet');
+
+const emptyFunction = require('emptyFunction');
+
+const {PropTypes} = React;
+
+import type {
+ NavigationParentState,
+ NavigationState,
+} from 'NavigationStateUtils';
+
+import type {
+ Layout,
+ OverlayRenderer,
+ Position,
+ SceneRenderer,
+} from 'NavigationAnimatedView';
+
+type Props = {
+ navigationState: NavigationParentState,
+ renderOverlay: OverlayRenderer,
+ renderScene: SceneRenderer,
+};
+
+/**
+ * A controlled navigation view that renders a list of cards.
+ */
+class NavigationCardStack extends React.Component {
+ _renderScene : SceneRenderer;
+
+ constructor(props: Props, context: any) {
+ super(props, context);
+ this._renderScene = this._renderScene.bind(this);
+ }
+
+ render(): ReactElement {
+ return (
+
+ );
+ }
+
+ _renderScene(
+ navigationState: NavigationState,
+ index: number,
+ position: Position,
+ layout: Layout,
+ ): ReactElement {
+ return (
+
+ {this.props.renderScene(navigationState, index, position, layout)}
+
+ );
+ }
+}
+
+NavigationCardStack.propTypes = {
+ navigationState: PropTypes.object.isRequired,
+ renderOverlay: PropTypes.func,
+ renderScene: PropTypes.func.isRequired,
+};
+
+NavigationCardStack.defaultProps = {
+ renderOverlay: emptyFunction.thatReturnsNull,
+};
+
+const styles = StyleSheet.create({
+ animatedView: {
+ flex: 1,
+ },
+});
+
+module.exports = NavigationContainer.create(NavigationCardStack);
diff --git a/Libraries/NavigationExperimental/NavigationAnimatedView.js b/Libraries/NavigationExperimental/NavigationAnimatedView.js
index c1f6a4040..a1f5df0f3 100644
--- a/Libraries/NavigationExperimental/NavigationAnimatedView.js
+++ b/Libraries/NavigationExperimental/NavigationAnimatedView.js
@@ -75,10 +75,12 @@ type OverlayRenderer = (
layout: Layout
) => ReactElement;
+type Position = Animated.Value;
+
type SceneRenderer = (
state: NavigationState,
index: number,
- position: Animated.Value,
+ position: Position,
layout: Layout
) => ReactElement;
diff --git a/Libraries/NavigationExperimental/NavigationExperimental.js b/Libraries/NavigationExperimental/NavigationExperimental.js
index 0100fa69c..f9153ea68 100644
--- a/Libraries/NavigationExperimental/NavigationExperimental.js
+++ b/Libraries/NavigationExperimental/NavigationExperimental.js
@@ -13,10 +13,11 @@
const NavigationAnimatedView = require('NavigationAnimatedView');
const NavigationCard = require('NavigationCard');
+const NavigationCardStack = require('NavigationCardStack');
const NavigationContainer = require('NavigationContainer');
const NavigationHeader = require('NavigationHeader');
-const NavigationRootContainer = require('NavigationRootContainer');
const NavigationReducer = require('NavigationReducer');
+const NavigationRootContainer = require('NavigationRootContainer');
const NavigationStateUtils = require('NavigationStateUtils');
const NavigationView = require('NavigationView');
@@ -36,6 +37,7 @@ const NavigationExperimental = {
// CustomComponents:
Header: NavigationHeader,
Card: NavigationCard,
+ CardStack: NavigationCardStack,
};
module.exports = NavigationExperimental;