From 6bcb2a05eb4eb2d614991d3c68351d101f6f1c76 Mon Sep 17 00:00:00 2001 From: Hedger Wang Date: Wed, 24 Feb 2016 18:51:09 -0800 Subject: [PATCH] Introducing NavigationCardStack Summary:Basic implementation of the component NavigationCardStack that animates a list of NavigationCard. This will be used to port the UX of teh current Navigator. Reviewed By: ericvicenti, fkgozali Differential Revision: D2967065 fb-gh-sync-id: a72920e141364fab328e45a083aef21ca5e6fe0c shipit-source-id: a72920e141364fab328e45a083aef21ca5e6fe0c --- .../NavigationCardStackExample.js | 114 +++++++++++++++++ .../NavigationExperimentalExample.js | 1 + .../NavigationCardStack.js | 115 ++++++++++++++++++ .../NavigationAnimatedView.js | 4 +- .../NavigationExperimental.js | 4 +- 5 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 Examples/UIExplorer/NavigationExperimental/NavigationCardStackExample.js create mode 100644 Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js 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;