diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationAnimatedValueSubscription.js b/Libraries/CustomComponents/NavigationExperimental/NavigationAnimatedValueSubscription.js deleted file mode 100644 index 5f0690712..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationAnimatedValueSubscription.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * 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 NavigationAnimatedValueSubscription - * @flow - */ -'use strict'; - -import type { - NavigationAnimatedValue -} from 'NavigationTypeDefinition'; - -class NavigationAnimatedValueSubscription { - _value: NavigationAnimatedValue; - _token: string; - - constructor(value: NavigationAnimatedValue, callback: Function) { - this._value = value; - this._token = value.addListener(callback); - } - - remove(): void { - this._value.removeListener(this._token); - } -} - -module.exports = NavigationAnimatedValueSubscription; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationCard.js b/Libraries/CustomComponents/NavigationExperimental/NavigationCard.js deleted file mode 100644 index e2f42fed3..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationCard.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NavigationCard - * @flow - */ -'use strict'; - -const Animated = require('Animated'); -const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder'); -const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator'); -const NavigationPagerPanResponder = require('NavigationPagerPanResponder'); -const NavigationPagerStyleInterpolator = require('NavigationPagerStyleInterpolator'); -const NavigationPointerEventsContainer = require('NavigationPointerEventsContainer'); -const NavigationPropTypes = require('NavigationPropTypes'); -const React = require('React'); -const StyleSheet = require('StyleSheet'); - -import type { - NavigationPanPanHandlers, - NavigationSceneRenderer, - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -type Props = NavigationSceneRendererProps & { - onComponentRef: (ref: any) => void, - onNavigateBack: ?Function, - panHandlers: ?NavigationPanPanHandlers, - pointerEvents: string, - renderScene: NavigationSceneRenderer, - style: any, -}; - -const {PropTypes} = React; - -/** - * Component that renders the scene as card for the . - */ -class NavigationCard extends React.Component { - props: Props; - - static propTypes = { - ...NavigationPropTypes.SceneRendererProps, - onComponentRef: PropTypes.func.isRequired, - onNavigateBack: PropTypes.func, - panHandlers: NavigationPropTypes.panHandlers, - pointerEvents: PropTypes.string.isRequired, - renderScene: PropTypes.func.isRequired, - style: PropTypes.any, - }; - - render(): React.Element { - const { - panHandlers, - pointerEvents, - renderScene, - style, - ...props /* NavigationSceneRendererProps */ - } = this.props; - - const viewStyle = style === undefined ? - NavigationCardStackStyleInterpolator.forHorizontal(props) : - style; - - const viewPanHandlers = panHandlers === undefined ? - NavigationCardStackPanResponder.forHorizontal({ - ...props, - onNavigateBack: this.props.onNavigateBack, - }) : - panHandlers; - - return ( - - {renderScene(props)} - - ); - } -} - -const styles = StyleSheet.create({ - main: { - backgroundColor: '#E9E9EF', - bottom: 0, - left: 0, - position: 'absolute', - right: 0, - shadowColor: 'black', - shadowOffset: {width: 0, height: 0}, - shadowOpacity: 0.4, - shadowRadius: 10, - top: 0, - }, -}); - -NavigationCard = NavigationPointerEventsContainer.create(NavigationCard); - -NavigationCard.CardStackPanResponder = NavigationCardStackPanResponder; -NavigationCard.CardStackStyleInterpolator = NavigationCardStackStyleInterpolator; -NavigationCard.PagerPanResponder = NavigationPagerPanResponder; -NavigationCard.PagerStyleInterpolator = NavigationPagerStyleInterpolator; - -module.exports = NavigationCard; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js b/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js deleted file mode 100644 index 3a54633e7..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js +++ /dev/null @@ -1,329 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NativeAnimatedModule = require('NativeModules').NativeAnimatedModule; -const NavigationCard = require('NavigationCard'); -const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder'); -const NavigationCardStackStyleInterpolator = require('NavigationCardStackStyleInterpolator'); -const NavigationPropTypes = require('NavigationPropTypes'); -const NavigationTransitioner = require('NavigationTransitioner'); -const React = require('React'); -const StyleSheet = require('StyleSheet'); -const View = require('View'); - -const {PropTypes} = React; -const {Directions} = NavigationCardStackPanResponder; - -import type { - NavigationState, - NavigationSceneRenderer, - NavigationSceneRendererProps, - NavigationTransitionProps, - NavigationStyleInterpolator, -} from 'NavigationTypeDefinition'; - -import type { - NavigationGestureDirection, -} from 'NavigationCardStackPanResponder'; - -type Props = { - direction: NavigationGestureDirection, - navigationState: NavigationState, - onNavigateBack?: Function, - renderHeader: ?NavigationSceneRenderer, - renderScene: NavigationSceneRenderer, - cardStyle?: any, - style: any, - gestureResponseDistance?: ?number, - enableGestures: ?boolean, - cardStyleInterpolator?: ?NavigationStyleInterpolator, - scenesStyle?: any, -}; - -type DefaultProps = { - direction: NavigationGestureDirection, - enableGestures: boolean, -}; - -/** - * A controlled navigation view that renders a stack of cards. - * - * ```html - * +------------+ - * +-| Header | - * +-+ |------------| - * | | | | - * | | | Focused | - * | | | Card | - * | | | | - * +-+ | | - * +-+ | - * +------------+ - * ``` - * - * ## Example - * - * ```js - * - * class App extends React.Component { - * constructor(props, context) { - * this.state = { - * navigation: { - * index: 0, - * routes: [ - * {key: 'page 1'}, - * }, - * }, - * }; - * } - * - * render() { - * return ( - * - * ); - * } - * - * _renderScene: (props) => { - * return ( - * - * {props.scene.route.key} - * - * ); - * }; - * ``` - */ -class NavigationCardStack extends React.Component { - _render : NavigationSceneRenderer; - _renderScene : NavigationSceneRenderer; - - static propTypes = { - /** - * Custom style applied to the card. - */ - cardStyle: PropTypes.any, - - /** - * Direction of the cards movement. Value could be `horizontal` or - * `vertical`. Default value is `horizontal`. - */ - direction: PropTypes.oneOf([Directions.HORIZONTAL, Directions.VERTICAL]), - - /** - * The distance from the edge of the card which gesture response can start - * for. Default value is `30`. - */ - gestureResponseDistance: PropTypes.number, - - /** - * An interpolator function that is passed an object parameter of type - * NavigationSceneRendererProps and should return a style object to apply to - * the transitioning navigation card. - * - * Default interpolator transitions translateX, scale, and opacity. - */ - cardStyleInterpolator: PropTypes.func, - - /** - * Enable gestures. Default value is true. - * - * When disabled, transition animations will be handled natively, which - * improves performance of the animation. In future iterations, gestures - * will also work with native-driven animation. - */ - enableGestures: PropTypes.bool, - - /** - * The controlled navigation state. Typically, the navigation state - * look like this: - * - * ```js - * const navigationState = { - * index: 0, // the index of the selected route. - * routes: [ // A list of routes. - * {key: 'page 1'}, // The 1st route. - * {key: 'page 2'}, // The second route. - * ], - * }; - * ``` - */ - navigationState: NavigationPropTypes.navigationState.isRequired, - - /** - * Callback that is called when the "back" action is performed. - * This happens when the back button is pressed or the back gesture is - * performed. - */ - onNavigateBack: PropTypes.func, - - /** - * Function that renders the header. - */ - renderHeader: PropTypes.func, - - /** - * Function that renders the a scene for a route. - */ - renderScene: PropTypes.func.isRequired, - - /** - * Custom style applied to the cards stack. - */ - style: View.propTypes.style, - - /** - * Custom style applied to the scenes stack. - */ - scenesStyle: View.propTypes.style, - }; - - static defaultProps: DefaultProps = { - direction: Directions.HORIZONTAL, - enableGestures: true, - }; - - constructor(props: Props, context: any) { - super(props, context); - } - - componentWillMount(): void { - this._render = this._render.bind(this); - this._renderScene = this._renderScene.bind(this); - } - - render(): React.Element { - return ( - - ); - } - - _configureTransition = () => { - const isVertical = this.props.direction === 'vertical'; - const animationConfig = {}; - if ( - !!NativeAnimatedModule - - // Gestures do not work with the current iteration of native animation - // driving. When gestures are disabled, we can drive natively. - && !this.props.enableGestures - - // Native animation support also depends on the transforms used: - && NavigationCardStackStyleInterpolator.canUseNativeDriver(isVertical) - ) { - animationConfig.useNativeDriver = true; - } - return animationConfig; - } - - _render(props: NavigationTransitionProps): React.Element { - const { - renderHeader, - } = this.props; - - const header = renderHeader ? {renderHeader(props)} : null; - - const scenes = props.scenes.map( - scene => this._renderScene({ - ...props, - scene, - }) - ); - - return ( - - - {scenes} - - {header} - - ); - } - - _renderScene(props: NavigationSceneRendererProps): React.Element { - const isVertical = this.props.direction === 'vertical'; - - const interpolator = this.props.cardStyleInterpolator || (isVertical ? - NavigationCardStackStyleInterpolator.forVertical : - NavigationCardStackStyleInterpolator.forHorizontal); - - const style = interpolator(props); - - let panHandlers = null; - - if (this.props.enableGestures) { - const panHandlersProps = { - ...props, - onNavigateBack: this.props.onNavigateBack, - gestureResponseDistance: this.props.gestureResponseDistance, - }; - panHandlers = isVertical ? - NavigationCardStackPanResponder.forVertical(panHandlersProps) : - NavigationCardStackPanResponder.forHorizontal(panHandlersProps); - } - - return ( - - ); - } -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - // Header is physically rendered after scenes so that Header won't be - // covered by the shadows of the scenes. - // That said, we'd have use `flexDirection: 'column-reverse'` to move - // Header above the scenes. - flexDirection: 'column-reverse', - }, - scenes: { - flex: 1, - }, -}); - -module.exports = NavigationCardStack; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackPanResponder.js b/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackPanResponder.js deleted file mode 100644 index 6ebf06610..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackPanResponder.js +++ /dev/null @@ -1,271 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationCardStackPanResponder - * @flow - */ -'use strict'; - -const Animated = require('Animated'); -const I18nManager = require('I18nManager'); -const NavigationAbstractPanResponder = require('NavigationAbstractPanResponder'); - -const clamp = require('clamp'); - -import type { - NavigationPanPanHandlers, - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -const emptyFunction = () => {}; - -/** - * The duration of the card animation in milliseconds. - */ -const ANIMATION_DURATION = 250; - -/** - * The threshold to invoke the `onNavigateBack` action. - * For instance, `1 / 3` means that moving greater than 1 / 3 of the width of - * the view will navigate. - */ -const POSITION_THRESHOLD = 1 / 3; - -/** - * The threshold (in pixels) to start the gesture action. - */ -const RESPOND_THRESHOLD = 15; - -/** - * The threshold (in pixels) to finish the gesture action. - */ -const DISTANCE_THRESHOLD = 100; - -/** - * Primitive gesture directions. - */ -const Directions = { - 'HORIZONTAL': 'horizontal', - 'VERTICAL': 'vertical', -}; - -export type NavigationGestureDirection = 'horizontal' | 'vertical'; - -type Props = NavigationSceneRendererProps & { - onNavigateBack: ?Function, - /** - * The distance from the edge of the navigator which gesture response can start for. - **/ - gestureResponseDistance: ?number, -}; - -/** - * Pan responder that handles gesture for a card in the cards stack. - * - * +------------+ - * +-+ | - * +-+ | | - * | | | | - * | | | Focused | - * | | | Card | - * | | | | - * +-+ | | - * +-+ | - * +------------+ - */ -class NavigationCardStackPanResponder extends NavigationAbstractPanResponder { - - _isResponding: boolean; - _isVertical: boolean; - _props: Props; - _startValue: number; - - constructor( - direction: NavigationGestureDirection, - props: Props, - ) { - super(); - this._isResponding = false; - this._isVertical = direction === Directions.VERTICAL; - this._props = props; - this._startValue = 0; - - // Hack to make this work with native driven animations. We add a single listener - // so the JS value of the following animated values gets updated. We rely on - // some Animated private APIs and not doing so would require using a bunch of - // value listeners but we'd have to remove them to not leak and I'm not sure - // when we'd do that with the current structure we have. `stopAnimation` callback - // is also broken with native animated values that have no listeners so if we - // want to remove this we have to fix this too. - this._addNativeListener(this._props.layout.width); - this._addNativeListener(this._props.layout.height); - this._addNativeListener(this._props.position); - } - - onMoveShouldSetPanResponder(event: any, gesture: any): boolean { - const props = this._props; - - if (props.navigationState.index !== props.scene.index) { - return false; - } - - const layout = props.layout; - const isVertical = this._isVertical; - const index = props.navigationState.index; - const currentDragDistance = gesture[isVertical ? 'dy' : 'dx']; - const currentDragPosition = gesture[isVertical ? 'moveY' : 'moveX']; - const maxDragDistance = isVertical ? - layout.height.__getValue() : - layout.width.__getValue(); - - const positionMax = isVertical ? - props.gestureResponseDistance : - /** - * For horizontal scroll views, a distance of 30 from the left of the screen is the - * standard maximum position to start touch responsiveness. - */ - props.gestureResponseDistance || 30; - - if (positionMax != null && currentDragPosition > positionMax) { - return false; - } - - return ( - Math.abs(currentDragDistance) > RESPOND_THRESHOLD && - maxDragDistance > 0 && - index > 0 - ); - } - - onPanResponderGrant(): void { - this._isResponding = false; - this._props.position.stopAnimation((value: number) => { - this._isResponding = true; - this._startValue = value; - }); - } - - onPanResponderMove(event: any, gesture: any): void { - if (!this._isResponding) { - return; - } - - const props = this._props; - const layout = props.layout; - const isVertical = this._isVertical; - const axis = isVertical ? 'dy' : 'dx'; - const index = props.navigationState.index; - const distance = isVertical ? - layout.height.__getValue() : - layout.width.__getValue(); - const currentValue = I18nManager.isRTL && axis === 'dx' ? - this._startValue + (gesture[axis] / distance) : - this._startValue - (gesture[axis] / distance); - - const value = clamp( - index - 1, - currentValue, - index - ); - - props.position.setValue(value); - } - - onPanResponderRelease(event: any, gesture: any): void { - if (!this._isResponding) { - return; - } - - this._isResponding = false; - - const props = this._props; - const isVertical = this._isVertical; - const axis = isVertical ? 'dy' : 'dx'; - const index = props.navigationState.index; - const distance = I18nManager.isRTL && axis === 'dx' ? - -gesture[axis] : - gesture[axis]; - - props.position.stopAnimation((value: number) => { - this._reset(); - - if (!props.onNavigateBack) { - return; - } - - if ( - distance > DISTANCE_THRESHOLD || - value <= index - POSITION_THRESHOLD - ) { - props.onNavigateBack(); - } - }); - } - - onPanResponderTerminate(): void { - this._isResponding = false; - this._reset(); - } - - _reset(): void { - const props = this._props; - Animated.timing( - props.position, - { - toValue: props.navigationState.index, - duration: ANIMATION_DURATION, - useNativeDriver: props.position.__isNative, - } - ).start(); - } - - _addNativeListener(animatedValue) { - if (!animatedValue.__isNative) { - return; - } - - if (Object.keys(animatedValue._listeners).length === 0) { - animatedValue.addListener(emptyFunction); - } - } -} - -function createPanHandlers( - direction: NavigationGestureDirection, - props: Props, -): NavigationPanPanHandlers { - const responder = new NavigationCardStackPanResponder(direction, props); - return responder.panHandlers; -} - -function forHorizontal( - props: Props, -): NavigationPanPanHandlers { - return createPanHandlers(Directions.HORIZONTAL, props); -} - -function forVertical( - props: Props, -): NavigationPanPanHandlers { - return createPanHandlers(Directions.VERTICAL, props); -} - -module.exports = { - // constants - ANIMATION_DURATION, - DISTANCE_THRESHOLD, - POSITION_THRESHOLD, - RESPOND_THRESHOLD, - - // enums - Directions, - - // methods. - forHorizontal, - forVertical, -}; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackStyleInterpolator.js b/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackStyleInterpolator.js deleted file mode 100644 index e3ef1ad05..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackStyleInterpolator.js +++ /dev/null @@ -1,176 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NavigationCardStackStyleInterpolator - * @flow - */ -'use strict'; - -const I18nManager = require('I18nManager'); - -import type { - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -/** - * Utility that builds the style for the card in the cards stack. - * - * +------------+ - * +-+ | - * +-+ | | - * | | | | - * | | | Focused | - * | | | Card | - * | | | | - * +-+ | | - * +-+ | - * +------------+ - */ - -/** - * Render the initial style when the initial layout isn't measured yet. - */ -function forInitial(props: NavigationSceneRendererProps): Object { - const { - navigationState, - scene, - } = props; - - const focused = navigationState.index === scene.index; - const opacity = focused ? 1 : 0; - // If not focused, move the scene to the far away. - const translate = focused ? 0 : 1000000; - return { - opacity, - transform: [ - { translateX: translate }, - { translateY: translate }, - ], - }; -} - -function forHorizontal(props: NavigationSceneRendererProps): Object { - const { - layout, - position, - scene, - } = props; - - if (!layout.isMeasured) { - return forInitial(props); - } - - const index = scene.index; - const inputRange = [index - 1, index, index + 0.99, index + 1]; - const width = layout.initWidth; - const outputRange = I18nManager.isRTL ? - ([-width, 0, 10, 10]: Array) : - ([width, 0, -10, -10]: Array); - - - const opacity = position.interpolate({ - inputRange, - outputRange: ([1, 1, 0.3, 0]: Array), - }); - - const scale = position.interpolate({ - inputRange, - outputRange: ([1, 1, 0.95, 0.95]: Array), - }); - - const translateY = 0; - const translateX = position.interpolate({ - inputRange, - outputRange, - }); - - return { - opacity, - transform: [ - { scale }, - { translateX }, - { translateY }, - ], - }; -} - -function forVertical(props: NavigationSceneRendererProps): Object { - const { - layout, - position, - scene, - } = props; - - if (!layout.isMeasured) { - return forInitial(props); - } - - const index = scene.index; - const inputRange = [index - 1, index, index + 0.99, index + 1]; - const height = layout.initHeight; - - const opacity = position.interpolate({ - inputRange, - outputRange: ([1, 1, 0.3, 0]: Array), - }); - - const scale = position.interpolate({ - inputRange, - outputRange: ([1, 1, 0.95, 0.95]: Array), - }); - - const translateX = 0; - const translateY = position.interpolate({ - inputRange, - outputRange: ([height, 0, -10, -10]: Array), - }); - - return { - opacity, - transform: [ - { scale }, - { translateX }, - { translateY }, - ], - }; -} - -function canUseNativeDriver(isVertical: boolean): boolean { - // The native driver can be enabled for this interpolator because the scale, - // translateX, and translateY transforms are supported with the native - // animation driver. - - return true; -} - -module.exports = { - forHorizontal, - forVertical, - canUseNativeDriver, -}; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationHeader.js b/Libraries/CustomComponents/NavigationExperimental/NavigationHeader.js deleted file mode 100644 index 5218a4c05..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationHeader.js +++ /dev/null @@ -1,282 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NavigationHeader - * @flow - */ -'use strict'; - -const NavigationHeaderBackButton = require('NavigationHeaderBackButton'); -const NavigationHeaderStyleInterpolator = require('NavigationHeaderStyleInterpolator'); -const NavigationHeaderTitle = require('NavigationHeaderTitle'); -const NavigationPropTypes = require('NavigationPropTypes'); -const React = require('React'); -const ReactNative = require('react-native'); -const TVEventHandler = require('TVEventHandler'); - -const { - Animated, - Platform, - StyleSheet, - View, -} = ReactNative; - -import type { - NavigationSceneRendererProps, - NavigationStyleInterpolator, -} from 'NavigationTypeDefinition'; - -type SubViewProps = NavigationSceneRendererProps & { - onNavigateBack: ?Function, -}; - -type SubViewRenderer = (subViewProps: SubViewProps) => ?React.Element; - -type DefaultProps = { - renderLeftComponent: SubViewRenderer, - renderRightComponent: SubViewRenderer, - renderTitleComponent: SubViewRenderer, - statusBarHeight: number | Animated.Value, -}; - -type Props = NavigationSceneRendererProps & { - onNavigateBack: ?Function, - renderLeftComponent: SubViewRenderer, - renderRightComponent: SubViewRenderer, - renderTitleComponent: SubViewRenderer, - style?: any, - viewProps?: any, - statusBarHeight: number | Animated.Value, -}; - -type SubViewName = 'left' | 'title' | 'right'; - -const APPBAR_HEIGHT = Platform.OS === 'ios' ? 44 : 56; -const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 20 : 0; -const {PropTypes} = React; - -class NavigationHeader extends React.PureComponent { - props: Props; - - static defaultProps = { - - renderTitleComponent: (props: SubViewProps) => { - const title = String(props.scene.route.title || ''); - return {title}; - }, - - renderLeftComponent: (props: SubViewProps) => { - if (props.scene.index === 0 || !props.onNavigateBack) { - return null; - } - return ( - - ); - }, - - renderRightComponent: (props: SubViewProps) => { - return null; - }, - - statusBarHeight: STATUSBAR_HEIGHT, - }; - - static propTypes = { - ...NavigationPropTypes.SceneRendererProps, - onNavigateBack: PropTypes.func, - renderLeftComponent: PropTypes.func, - renderRightComponent: PropTypes.func, - renderTitleComponent: PropTypes.func, - style: View.propTypes.style, - statusBarHeight: PropTypes.number, - viewProps: PropTypes.shape(View.propTypes), - }; - - _tvEventHandler: TVEventHandler; - - componentDidMount(): void { - this._tvEventHandler = new TVEventHandler(); - this._tvEventHandler.enable(this, function(cmp, evt) { - if (evt && evt.eventType === 'menu') { - cmp.props.onNavigateBack && cmp.props.onNavigateBack(); - } - }); - } - - componentWillUnmount(): void { - if (this._tvEventHandler) { - this._tvEventHandler.disable(); - delete this._tvEventHandler; - } - } - - render(): React.Element { - const { scenes, style, viewProps } = this.props; - - const scenesProps = scenes.map(scene => { - const props = NavigationPropTypes.extractSceneRendererProps(this.props); - props.scene = scene; - return props; - }); - - const barHeight = (this.props.statusBarHeight instanceof Animated.Value) - ? Animated.add(this.props.statusBarHeight, new Animated.Value(APPBAR_HEIGHT)) - : APPBAR_HEIGHT + this.props.statusBarHeight; - - return ( - - {scenesProps.map(this._renderLeft, this)} - {scenesProps.map(this._renderTitle, this)} - {scenesProps.map(this._renderRight, this)} - - ); - } - - _renderLeft = (props: NavigationSceneRendererProps): ?React.Element => { - return this._renderSubView( - props, - 'left', - this.props.renderLeftComponent, - NavigationHeaderStyleInterpolator.forLeft, - ); - }; - - _renderTitle = (props: NavigationSceneRendererProps): ?React.Element => { - return this._renderSubView( - props, - 'title', - this.props.renderTitleComponent, - NavigationHeaderStyleInterpolator.forCenter, - ); - }; - - _renderRight = (props: NavigationSceneRendererProps): ?React.Element => { - return this._renderSubView( - props, - 'right', - this.props.renderRightComponent, - NavigationHeaderStyleInterpolator.forRight, - ); - }; - - _renderSubView( - props: NavigationSceneRendererProps, - name: SubViewName, - renderer: SubViewRenderer, - styleInterpolator: NavigationStyleInterpolator, - ): ?React.Element { - const { - scene, - navigationState, - } = props; - - const { - index, - isStale, - key, - } = scene; - - const offset = navigationState.index - index; - - if (Math.abs(offset) > 2) { - // Scene is far away from the active scene. Hides it to avoid unnecessary - // rendering. - return null; - } - - const subViewProps = {...props, onNavigateBack: this.props.onNavigateBack}; - const subView = renderer(subViewProps); - if (subView === null) { - return null; - } - - const pointerEvents = offset !== 0 || isStale ? 'none' : 'box-none'; - return ( - - {subView} - - ); - } - - static HEIGHT = APPBAR_HEIGHT + STATUSBAR_HEIGHT; - static Title = NavigationHeaderTitle; - static BackButton = NavigationHeaderBackButton; - -} - -const styles = StyleSheet.create({ - appbar: { - alignItems: 'center', - backgroundColor: Platform.OS === 'ios' ? '#EFEFF2' : '#FFF', - borderBottomColor: 'rgba(0, 0, 0, .15)', - borderBottomWidth: Platform.OS === 'ios' ? StyleSheet.hairlineWidth : 0, - elevation: 4, - flexDirection: 'row', - justifyContent: 'flex-start', - }, - - title: { - bottom: 0, - left: APPBAR_HEIGHT, - position: 'absolute', - right: APPBAR_HEIGHT, - top: 0, - }, - - left: { - bottom: 0, - left: 0, - position: 'absolute', - top: 0, - }, - - right: { - bottom: 0, - position: 'absolute', - right: 0, - top: 0, - }, -}); - -module.exports = NavigationHeader; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderBackButton.js b/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderBackButton.js deleted file mode 100644 index f3e901f3f..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderBackButton.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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. - * - * @providesModule NavigationHeaderBackButton - * @flow -*/ -'use strict'; - -const React = require('react'); -const ReactNative = require('react-native'); - -const { - I18nManager, - Image, - Platform, - StyleSheet, - TouchableOpacity, -} = ReactNative; - -type Props = { - imageStyle?: any, - onPress: Function, - style?: any, -}; - -const NavigationHeaderBackButton = (props: Props) => ( - - - -); - -NavigationHeaderBackButton.propTypes = { - onPress: React.PropTypes.func.isRequired -}; - -const styles = StyleSheet.create({ - buttonContainer: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - }, - button: { - height: 24, - width: 24, - margin: Platform.OS === 'ios' ? 10 : 16, - resizeMode: 'contain', - transform: [{scaleX: I18nManager.isRTL ? -1 : 1}], - } -}); - -module.exports = NavigationHeaderBackButton; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderStyleInterpolator.js b/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderStyleInterpolator.js deleted file mode 100644 index 38a8689c0..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderStyleInterpolator.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NavigationHeaderStyleInterpolator - * @flow - */ -'use strict'; - -const I18nManager = require('I18nManager'); - -import type { - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -/** - * Utility that builds the style for the navigation header. - * - * +-------------+-------------+-------------+ - * | | | | - * | Left | Title | Right | - * | Component | Component | Component | - * | | | | - * +-------------+-------------+-------------+ - */ - -function forLeft(props: NavigationSceneRendererProps): Object { - const {position, scene} = props; - const {index} = scene; - return { - opacity: position.interpolate({ - inputRange: [ index - 1, index, index + 1 ], - outputRange: ([ 0, 1, 0 ]: Array), - }), - }; -} - -function forCenter(props: NavigationSceneRendererProps): Object { - const {position, scene} = props; - const {index} = scene; - return { - opacity:position.interpolate({ - inputRange: [ index - 1, index, index + 1 ], - outputRange: ([ 0, 1, 0 ]: Array), - }), - transform: [ - { - translateX: position.interpolate({ - inputRange: [ index - 1, index + 1 ], - outputRange: I18nManager.isRTL ? - ([ -200, 200 ]: Array) : - ([ 200, -200 ]: Array), - }), - } - ], - }; -} - -function forRight(props: NavigationSceneRendererProps): Object { - const {position, scene} = props; - const {index} = scene; - return { - opacity: position.interpolate({ - inputRange: [ index - 1, index, index + 1 ], - outputRange: ([ 0, 1, 0 ]: Array), - }), - }; -} - -module.exports = { - forCenter, - forLeft, - forRight, -}; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderTitle.js b/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderTitle.js deleted file mode 100644 index 61d39d460..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderTitle.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NavigationHeaderTitle - * @flow - */ -'use strict'; - -const React = require('react'); -const ReactNative = require('react-native'); - -const { - Platform, - StyleSheet, - View, - Text, -} = ReactNative; - -type Props = { - children?: React.Element, - style?: any, - textStyle?: any, - viewProps?: any, -} - -const NavigationHeaderTitle = ({ children, style, textStyle, viewProps }: Props) => ( - - {children} - -); - -const styles = StyleSheet.create({ - title: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - marginHorizontal: 16 - }, - - titleText: { - flex: 1, - fontSize: 18, - fontWeight: '500', - color: 'rgba(0, 0, 0, .9)', - textAlign: Platform.OS === 'ios' ? 'center' : 'left' - } -}); - -NavigationHeaderTitle.propTypes = { - children: React.PropTypes.node.isRequired, - style: View.propTypes.style, - textStyle: Text.propTypes.style -}; - -module.exports = NavigationHeaderTitle; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationPagerPanResponder.js b/Libraries/CustomComponents/NavigationExperimental/NavigationPagerPanResponder.js deleted file mode 100644 index 1cc071ed6..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationPagerPanResponder.js +++ /dev/null @@ -1,238 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationPagerPanResponder - * @flow - */ -'use strict'; - -const Animated = require('Animated'); -const NavigationAbstractPanResponder = require('NavigationAbstractPanResponder'); -const NavigationCardStackPanResponder = require('NavigationCardStackPanResponder'); -const I18nManager = require('I18nManager'); - -const clamp = require('clamp'); - -import type { - NavigationPanPanHandlers, - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -import type { - NavigationGestureDirection, -} from 'NavigationCardStackPanResponder'; - -type Props = NavigationSceneRendererProps & { - onNavigateBack: ?Function, - onNavigateForward: ?Function, -}; - -/** - * Primitive gesture directions. - */ -const { - ANIMATION_DURATION, - POSITION_THRESHOLD, - RESPOND_THRESHOLD, - Directions, -} = NavigationCardStackPanResponder; - -/** - * The threshold (in pixels) to finish the gesture action. - */ -const DISTANCE_THRESHOLD = 50; - -/** - * The threshold to trigger the gesture action. This determines the rate of the - * flick when the action will be triggered - */ -const VELOCITY_THRESHOLD = 1.5; - -/** - * Pan responder that handles gesture for a card in the cards list. - * - * +-------------+-------------+-------------+ - * | | | | - * | | | | - * | | | | - * | Next | Focused | Previous | - * | Card | Card | Card | - * | | | | - * | | | | - * | | | | - * +-------------+-------------+-------------+ - */ -class NavigationPagerPanResponder extends NavigationAbstractPanResponder { - - _isResponding: boolean; - _isVertical: boolean; - _props: Props; - _startValue: number; - - constructor( - direction: NavigationGestureDirection, - props: Props, - ) { - super(); - this._isResponding = false; - this._isVertical = direction === Directions.VERTICAL; - this._props = props; - this._startValue = 0; - } - - onMoveShouldSetPanResponder(event: any, gesture: any): boolean { - const props = this._props; - - if (props.navigationState.index !== props.scene.index) { - return false; - } - - const layout = props.layout; - const isVertical = this._isVertical; - const axis = isVertical ? 'dy' : 'dx'; - const index = props.navigationState.index; - const distance = isVertical ? - layout.height.__getValue() : - layout.width.__getValue(); - - return ( - Math.abs(gesture[axis]) > RESPOND_THRESHOLD && - distance > 0 && - index >= 0 - ); - } - - onPanResponderGrant(): void { - this._isResponding = false; - this._props.position.stopAnimation((value: number) => { - this._isResponding = true; - this._startValue = value; - }); - } - - onPanResponderMove(event: any, gesture: any): void { - if (!this._isResponding) { - return; - } - - const { - layout, - navigationState, - position, - scenes, - } = this._props; - - const isVertical = this._isVertical; - const axis = isVertical ? 'dy' : 'dx'; - const index = navigationState.index; - const distance = isVertical ? - layout.height.__getValue() : - layout.width.__getValue(); - const currentValue = I18nManager.isRTL && axis === 'dx' ? - this._startValue + (gesture[axis] / distance) : - this._startValue - (gesture[axis] / distance); - - const prevIndex = Math.max( - 0, - index - 1, - ); - - const nextIndex = Math.min( - index + 1, - scenes.length - 1, - ); - - const value = clamp( - prevIndex, - currentValue, - nextIndex, - ); - - position.setValue(value); - } - - onPanResponderRelease(event: any, gesture: any): void { - if (!this._isResponding) { - return; - } - - this._isResponding = false; - - const { - navigationState, - onNavigateBack, - onNavigateForward, - position, - } = this._props; - - const isVertical = this._isVertical; - const axis = isVertical ? 'dy' : 'dx'; - const velocityAxis = isVertical ? 'vy' : 'vx'; - const index = navigationState.index; - const distance = I18nManager.isRTL && axis === 'dx' ? - -gesture[axis] : - gesture[axis]; - const moveSpeed = I18nManager.isRTL && velocityAxis === 'vx' ? - -gesture[velocityAxis] : - gesture[velocityAxis]; - - position.stopAnimation((value: number) => { - this._reset(); - if ( - distance > DISTANCE_THRESHOLD || - value <= index - POSITION_THRESHOLD || - moveSpeed > VELOCITY_THRESHOLD - ) { - onNavigateBack && onNavigateBack(); - return; - } - - if ( - distance < -DISTANCE_THRESHOLD || - value >= index + POSITION_THRESHOLD || - moveSpeed < -VELOCITY_THRESHOLD - ) { - onNavigateForward && onNavigateForward(); - } - }); - } - - onPanResponderTerminate(): void { - this._isResponding = false; - this._reset(); - } - - _reset(): void { - const props = this._props; - Animated.timing( - props.position, - { - toValue: props.navigationState.index, - duration: ANIMATION_DURATION, - } - ).start(); - } -} - -function createPanHandlers( - direction: NavigationGestureDirection, - props: Props, -): NavigationPanPanHandlers { - const responder = new NavigationPagerPanResponder(direction, props); - return responder.panHandlers; -} - -function forHorizontal( - props: Props, -): NavigationPanPanHandlers { - return createPanHandlers(Directions.HORIZONTAL, props); -} - -module.exports = { - forHorizontal, -}; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolator.js b/Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolator.js deleted file mode 100644 index 950aa5eb1..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolator.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NavigationPagerStyleInterpolator - * @flow - */ -'use strict'; - -const I18nManager = require('I18nManager'); - -import type { - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -/** - * Utility that builds the style for the card in the cards list. - * - * +-------------+-------------+-------------+ - * | | | | - * | | | | - * | | | | - * | Next | Focused | Previous | - * | Card | Card | Card | - * | | | | - * | | | | - * | | | | - * +-------------+-------------+-------------+ - */ - -/** - * Render the initial style when the initial layout isn't measured yet. - */ -function forInitial(props: NavigationSceneRendererProps): Object { - const { - navigationState, - scene, - } = props; - - const focused = navigationState.index === scene.index; - const opacity = focused ? 1 : 0; - // If not focused, move the scene to the far away. - const dir = scene.index > navigationState.index ? 1 : -1; - const translate = focused ? 0 : (1000000 * dir); - return { - opacity, - transform: [ - { translateX: translate }, - { translateY: translate }, - ], - }; -} - -function forHorizontal(props: NavigationSceneRendererProps): Object { - const { - layout, - position, - scene, - } = props; - - if (!layout.isMeasured) { - return forInitial(props); - } - - const index = scene.index; - const inputRange = [index - 1, index, index + 1]; - const width = layout.initWidth; - const outputRange = I18nManager.isRTL ? - ([-width, 0, width]: Array) : - ([width, 0, -width]: Array); - - const translateX = position.interpolate({ - inputRange, - outputRange, - }); - - return { - opacity : 1, - shadowColor: 'transparent', - shadowRadius: 0, - transform: [ - { scale: 1 }, - { translateX }, - { translateY: 0 }, - ], - }; -} - -module.exports = { - forHorizontal, -}; diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationPointerEventsContainer.js b/Libraries/CustomComponents/NavigationExperimental/NavigationPointerEventsContainer.js deleted file mode 100644 index a6ef36fc2..000000000 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationPointerEventsContainer.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * 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 NavigationPointerEventsContainer - * @flow - */ -'use strict'; - -const React = require('React'); -const NavigationAnimatedValueSubscription = require('NavigationAnimatedValueSubscription'); - -const invariant = require('fbjs/lib/invariant'); - -import type { - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -type Props = NavigationSceneRendererProps; - -const MIN_POSITION_OFFSET = 0.01; - -/** - * Create a higher-order component that automatically computes the - * `pointerEvents` property for a component whenever navigation position - * changes. - */ -function create( - Component: ReactClass, -): ReactClass { - - class Container extends React.Component { - - _component: any; - _onComponentRef: (view: any) => void; - _onPositionChange: (data: {value: number}) => void; - _pointerEvents: string; - _positionListener: ?NavigationAnimatedValueSubscription; - - props: Props; - - constructor(props: Props, context: any) { - super(props, context); - this._pointerEvents = this._computePointerEvents(); - } - - componentWillMount(): void { - this._onPositionChange = this._onPositionChange.bind(this); - this._onComponentRef = this._onComponentRef.bind(this); - } - - componentDidMount(): void { - this._bindPosition(this.props); - } - - componentWillUnmount(): void { - this._positionListener && this._positionListener.remove(); - } - - componentWillReceiveProps(nextProps: Props): void { - this._bindPosition(nextProps); - } - - render(): React.Element { - this._pointerEvents = this._computePointerEvents(); - return ( - - ); - } - - _onComponentRef(component: any): void { - this._component = component; - if (component) { - invariant( - typeof component.setNativeProps === 'function', - 'component must implement method `setNativeProps`', - ); - } - } - - _bindPosition(props: NavigationSceneRendererProps): void { - this._positionListener && this._positionListener.remove(); - this._positionListener = new NavigationAnimatedValueSubscription( - props.position, - this._onPositionChange, - ); - } - - _onPositionChange(): void { - if (this._component) { - const pointerEvents = this._computePointerEvents(); - if (this._pointerEvents !== pointerEvents) { - this._pointerEvents = pointerEvents; - this._component.setNativeProps({pointerEvents}); - } - } - } - - _computePointerEvents(): string { - const { - navigationState, - position, - scene, - } = this.props; - - if (scene.isStale || navigationState.index !== scene.index) { - // The scene isn't focused. - return scene.index > navigationState.index ? - 'box-only' : - 'none'; - } - - const offset = position.__getAnimatedValue() - navigationState.index; - if (Math.abs(offset) > MIN_POSITION_OFFSET) { - // The positon is still away from scene's index. - // Scene's children should not receive touches until the position - // is close enough to scene's index. - return 'box-only'; - } - - return 'auto'; - } - } - return Container; -} - -module.exports = { - create, -}; diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1.5x.android.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1.5x.android.png deleted file mode 100644 index ad03a63bf..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1.5x.android.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1.5x.ios.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1.5x.ios.png deleted file mode 100644 index e43fa0622..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1.5x.ios.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1x.android.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1x.android.png deleted file mode 100644 index 083db295f..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1x.android.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1x.ios.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1x.ios.png deleted file mode 100644 index 4244656b9..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@1x.ios.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@2x.android.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@2x.android.png deleted file mode 100644 index 6de0a1cbb..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@2x.android.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@2x.ios.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@2x.ios.png deleted file mode 100644 index a8b6e9a63..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@2x.ios.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@3x.android.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@3x.android.png deleted file mode 100644 index 15a983a67..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@3x.android.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@3x.ios.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@3x.ios.png deleted file mode 100644 index 07ea37b4e..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@3x.ios.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@4x.android.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@4x.android.png deleted file mode 100644 index 17e52e855..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@4x.android.png and /dev/null differ diff --git a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@4x.ios.png b/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@4x.ios.png deleted file mode 100644 index 7899053f6..000000000 Binary files a/Libraries/CustomComponents/NavigationExperimental/assets/back-icon@4x.ios.png and /dev/null differ diff --git a/Libraries/NavigationExperimental/NavigationAbstractPanResponder.js b/Libraries/NavigationExperimental/NavigationAbstractPanResponder.js deleted file mode 100644 index cd31dccdb..000000000 --- a/Libraries/NavigationExperimental/NavigationAbstractPanResponder.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationAbstractPanResponder - * @flow - */ -'use strict'; - -const PanResponder = require('PanResponder'); - -const invariant = require('fbjs/lib/invariant'); - -import type { - NavigationPanPanHandlers, -} from 'NavigationTypeDefinition'; - -const EmptyPanHandlers = { - onMoveShouldSetPanResponder: null, - onPanResponderGrant: null, - onPanResponderMove: null, - onPanResponderRelease: null, - onPanResponderTerminate: null, -}; - -/** - * Abstract class that defines the common interface of PanResponder that handles - * the gesture actions. - */ -class NavigationAbstractPanResponder { - - panHandlers: NavigationPanPanHandlers; - - constructor() { - const config = {}; - Object.keys(EmptyPanHandlers).forEach(name => { - const fn: any = (this: any)[name]; - - invariant( - typeof fn === 'function', - 'subclass of `NavigationAbstractPanResponder` must implement method %s', - name - ); - - config[name] = fn.bind(this); - }, this); - - this.panHandlers = PanResponder.create(config).panHandlers; - } -} - -module.exports = NavigationAbstractPanResponder; diff --git a/Libraries/NavigationExperimental/NavigationExperimental.js b/Libraries/NavigationExperimental/NavigationExperimental.js deleted file mode 100644 index c4fd955c8..000000000 --- a/Libraries/NavigationExperimental/NavigationExperimental.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationExperimental - * @flow - */ -'use strict'; - -const NavigationCard = require('NavigationCard'); -const NavigationCardStack = require('NavigationCardStack'); -const NavigationHeader = require('NavigationHeader'); -const NavigationPropTypes = require('NavigationPropTypes'); -const NavigationStateUtils = require('NavigationStateUtils'); -const NavigationTransitioner = require('NavigationTransitioner'); - -const warning = require('fbjs/lib/warning'); - -// This warning will only be reached if the user has required the module -warning( - false, - 'NavigationExperimental is deprecated and will be removed in a future ' + - 'version of React Native. The NavigationExperimental views live on in ' + - 'the React-Navigation project, which also makes it easy to declare ' + - 'navigation logic for your app. Learn more at https://reactnavigation.org/' -); - - -const NavigationExperimental = { - // Core - StateUtils: NavigationStateUtils, - - // Views - Transitioner: NavigationTransitioner, - - // CustomComponents: - Card: NavigationCard, - CardStack: NavigationCardStack, - Header: NavigationHeader, - - PropTypes: NavigationPropTypes, -}; - -module.exports = NavigationExperimental; diff --git a/Libraries/NavigationExperimental/NavigationPropTypes.js b/Libraries/NavigationExperimental/NavigationPropTypes.js deleted file mode 100644 index 1aed9e9d2..000000000 --- a/Libraries/NavigationExperimental/NavigationPropTypes.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationPropTypes - * @flow - */ -'use strict'; - -import type { - NavigationSceneRendererProps, -} from 'NavigationTypeDefinition'; - -/** - * React component PropTypes Definitions. Consider using this as a supplementary - * measure with `NavigationTypeDefinition`. This helps to capture the propType - * error at run-time, where as `NavigationTypeDefinition` capture the flow - * type check errors at build time. - */ - -const Animated = require('Animated'); -const React = require('React'); - -const {PropTypes} = React; - -/* NavigationAction */ -const action = PropTypes.shape({ - type: PropTypes.string.isRequired, -}); - -/* NavigationAnimatedValue */ -const animatedValue = PropTypes.instanceOf(Animated.Value); - -/* NavigationRoute */ -const navigationRoute = PropTypes.shape({ - key: PropTypes.string.isRequired, -}); - -/* NavigationState */ -const navigationState = PropTypes.shape({ - index: PropTypes.number.isRequired, - routes: PropTypes.arrayOf(navigationRoute), -}); - -/* NavigationLayout */ -const layout = PropTypes.shape({ - height: animatedValue, - initHeight: PropTypes.number.isRequired, - initWidth: PropTypes.number.isRequired, - isMeasured: PropTypes.bool.isRequired, - width: animatedValue, -}); - -/* NavigationScene */ -const scene = PropTypes.shape({ - index: PropTypes.number.isRequired, - isActive: PropTypes.bool.isRequired, - isStale: PropTypes.bool.isRequired, - key: PropTypes.string.isRequired, - route: navigationRoute.isRequired, -}); - -/* NavigationSceneRendererProps */ -const SceneRendererProps = { - layout: layout.isRequired, - navigationState: navigationState.isRequired, - position: animatedValue.isRequired, - progress: animatedValue.isRequired, - scene: scene.isRequired, - scenes: PropTypes.arrayOf(scene).isRequired, -}; - -const SceneRenderer = PropTypes.shape(SceneRendererProps); - -/* NavigationPanPanHandlers */ -const panHandlers = PropTypes.shape({ - onMoveShouldSetResponder: PropTypes.func.isRequired, - onMoveShouldSetResponderCapture: PropTypes.func.isRequired, - onResponderEnd: PropTypes.func.isRequired, - onResponderGrant: PropTypes.func.isRequired, - onResponderMove: PropTypes.func.isRequired, - onResponderReject: PropTypes.func.isRequired, - onResponderRelease: PropTypes.func.isRequired, - onResponderStart: PropTypes.func.isRequired, - onResponderTerminate: PropTypes.func.isRequired, - onResponderTerminationRequest: PropTypes.func.isRequired, - onStartShouldSetResponder: PropTypes.func.isRequired, - onStartShouldSetResponderCapture: PropTypes.func.isRequired, -}); - -/** - * Helper function that extracts the props needed for scene renderer. - */ -function extractSceneRendererProps( - props: NavigationSceneRendererProps, -): NavigationSceneRendererProps { - return { - layout: props.layout, - navigationState: props.navigationState, - position: props.position, - progress: props.progress, - scene: props.scene, - scenes: props.scenes, - }; -} - -module.exports = { - // helpers - extractSceneRendererProps, - - // Bundled propTypes. - SceneRendererProps, - - // propTypes - SceneRenderer, - action, - navigationState, - navigationRoute, - panHandlers, -}; diff --git a/Libraries/NavigationExperimental/NavigationStateUtils.js b/Libraries/NavigationExperimental/NavigationStateUtils.js deleted file mode 100644 index e6022c538..000000000 --- a/Libraries/NavigationExperimental/NavigationStateUtils.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationStateUtils - * @flow - */ -'use strict'; - -const invariant = require('fbjs/lib/invariant'); - -import type { - NavigationRoute, - NavigationState -} from 'NavigationTypeDefinition'; - -/** - * Utilities to perform atomic operation with navigate state and routes. - * - * ```javascript - * const state1 = {key: 'page 1'}; - * const state2 = NavigationStateUtils.push(state1, {key: 'page 2'}); - * ``` - */ -const NavigationStateUtils = { - - /** - * Gets a route by key. If the route isn't found, returns `null`. - */ - get(state: NavigationState, key: string): ?NavigationRoute { - return state.routes.find(route => route.key === key) || null; - }, - - /** - * Returns the first index at which a given route's key can be found in the - * routes of the navigation state, or -1 if it is not present. - */ - indexOf(state: NavigationState, key: string): number { - return state.routes.map(route => route.key).indexOf(key); - }, - - /** - * Returns `true` at which a given route's key can be found in the - * routes of the navigation state. - */ - has(state: NavigationState, key: string): boolean { - return !!state.routes.some(route => route.key === key); - }, - - /** - * Pushes a new route into the navigation state. - * Note that this moves the index to the positon to where the last route in the - * stack is at. - */ - push(state: NavigationState, route: NavigationRoute): NavigationState { - invariant( - NavigationStateUtils.indexOf(state, route.key) === -1, - 'should not push route with duplicated key %s', - route.key, - ); - - const routes = state.routes.slice(); - routes.push(route); - - return { - ...state, - index: routes.length - 1, - routes, - }; - }, - - /** - * Pops out a route from the navigation state. - * Note that this moves the index to the positon to where the last route in the - * stack is at. - */ - pop(state: NavigationState): NavigationState { - if (state.index <= 0) { - // [Note]: Over-popping does not throw error. Instead, it will be no-op. - return state; - } - const routes = state.routes.slice(0, -1); - return { - ...state, - index: routes.length - 1, - routes, - }; - }, - - /** - * Sets the focused route of the navigation state by index. - */ - jumpToIndex(state: NavigationState, index: number): NavigationState { - if (index === state.index) { - return state; - } - - invariant(!!state.routes[index], 'invalid index %s to jump to', index); - - return { - ...state, - index, - }; - }, - - /** - * Sets the focused route of the navigation state by key. - */ - jumpTo(state: NavigationState, key: string): NavigationState { - const index = NavigationStateUtils.indexOf(state, key); - return NavigationStateUtils.jumpToIndex(state, index); - }, - - /** - * Sets the focused route to the previous route. - */ - back(state: NavigationState): NavigationState { - const index = state.index - 1; - const route = state.routes[index]; - return route ? NavigationStateUtils.jumpToIndex(state, index) : state; - }, - - /** - * Sets the focused route to the next route. - */ - forward(state: NavigationState): NavigationState { - const index = state.index + 1; - const route = state.routes[index]; - return route ? NavigationStateUtils.jumpToIndex(state, index) : state; - }, - - /** - * Replace a route by a key. - * Note that this moves the index to the positon to where the new route in the - * stack is at. - */ - replaceAt( - state: NavigationState, - key: string, - route: NavigationRoute, - ): NavigationState { - const index = NavigationStateUtils.indexOf(state, key); - return NavigationStateUtils.replaceAtIndex(state, index, route); - }, - - /** - * Replace a route by a index. - * Note that this moves the index to the positon to where the new route in the - * stack is at. - */ - replaceAtIndex( - state: NavigationState, - index: number, - route: NavigationRoute, - ): NavigationState { - invariant( - !!state.routes[index], - 'invalid index %s for replacing route %s', - index, - route.key, - ); - - if (state.routes[index] === route) { - return state; - } - - const routes = state.routes.slice(); - routes[index] = route; - - return { - ...state, - index, - routes, - }; - }, - - /** - * Resets all routes. - * Note that this moves the index to the positon to where the last route in the - * stack is at if the param `index` isn't provided. - */ - reset( - state: NavigationState, - routes: Array, - index?: number, - ): NavigationState { - invariant( - routes.length && Array.isArray(routes), - 'invalid routes to replace', - ); - - const nextIndex: number = index === undefined ? routes.length - 1 : index; - - if (state.routes.length === routes.length && state.index === nextIndex) { - const compare = (route, ii) => routes[ii] === route; - if (state.routes.every(compare)) { - return state; - } - } - - invariant(!!routes[nextIndex], 'invalid index %s to reset', nextIndex); - - return { - ...state, - index: nextIndex, - routes, - }; - }, -}; - -module.exports = NavigationStateUtils; diff --git a/Libraries/NavigationExperimental/NavigationTransitioner.js b/Libraries/NavigationExperimental/NavigationTransitioner.js deleted file mode 100644 index 7edf96faf..000000000 --- a/Libraries/NavigationExperimental/NavigationTransitioner.js +++ /dev/null @@ -1,292 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationTransitioner - * @flow - */ -'use strict'; - -const Animated = require('Animated'); -const Easing = require('Easing'); -const NavigationPropTypes = require('NavigationPropTypes'); -const NavigationScenesReducer = require('NavigationScenesReducer'); -const React = require('React'); -const StyleSheet = require('StyleSheet'); -const View = require('View'); - -const invariant = require('fbjs/lib/invariant'); - -import type { - NavigationAnimatedValue, - NavigationLayout, - NavigationScene, - NavigationState, - NavigationTransitionProps, - NavigationTransitionSpec, -} from 'NavigationTypeDefinition'; - -type Props = { - configureTransition: ( - a: NavigationTransitionProps, - b: ?NavigationTransitionProps, - ) => NavigationTransitionSpec, - navigationState: NavigationState, - onTransitionEnd: () => void, - onTransitionStart: () => void, - render: (a: NavigationTransitionProps, b: ?NavigationTransitionProps) => any, - style: any, -}; - -type State = { - layout: NavigationLayout, - position: NavigationAnimatedValue, - progress: NavigationAnimatedValue, - scenes: Array, -}; - -const {PropTypes} = React; - -const DefaultTransitionSpec = { - duration: 250, - easing: Easing.inOut(Easing.ease), - timing: Animated.timing, -}; - -class NavigationTransitioner extends React.Component { - _onLayout: (event: any) => void; - _onTransitionEnd: () => void; - _prevTransitionProps: ?NavigationTransitionProps; - _transitionProps: NavigationTransitionProps; - _isMounted: boolean; - - props: Props; - state: State; - - static propTypes = { - configureTransition: PropTypes.func, - navigationState: NavigationPropTypes.navigationState.isRequired, - onTransitionEnd: PropTypes.func, - onTransitionStart: PropTypes.func, - render: PropTypes.func.isRequired, - }; - - constructor(props: Props, context: any) { - super(props, context); - - // The initial layout isn't measured. Measured layout will be only available - // when the component is mounted. - const layout = { - height: new Animated.Value(0), - initHeight: 0, - initWidth: 0, - isMeasured: false, - width: new Animated.Value(0), - }; - - this.state = { - layout, - position: new Animated.Value(this.props.navigationState.index), - progress: new Animated.Value(1), - scenes: NavigationScenesReducer([], this.props.navigationState), - }; - - this._prevTransitionProps = null; - this._transitionProps = buildTransitionProps(props, this.state); - this._isMounted = false; - } - - componentWillMount(): void { - this._onLayout = this._onLayout.bind(this); - this._onTransitionEnd = this._onTransitionEnd.bind(this); - } - - componentDidMount(): void { - this._isMounted = true; - } - - componentWillUnmount(): void { - this._isMounted = false; - } - - componentWillReceiveProps(nextProps: Props): void { - const nextScenes = NavigationScenesReducer( - this.state.scenes, - nextProps.navigationState, - this.props.navigationState - ); - - if (nextScenes === this.state.scenes) { - return; - } - - const nextState = { - ...this.state, - scenes: nextScenes, - }; - - const { - position, - progress, - } = nextState; - - progress.setValue(0); - - this._prevTransitionProps = this._transitionProps; - this._transitionProps = buildTransitionProps(nextProps, nextState); - - // get the transition spec. - const transitionUserSpec = nextProps.configureTransition ? - nextProps.configureTransition( - this._transitionProps, - this._prevTransitionProps, - ) : - null; - - const transitionSpec = { - ...DefaultTransitionSpec, - ...transitionUserSpec, - }; - - const {timing} = transitionSpec; - delete transitionSpec.timing; - - const animations = [ - timing( - progress, - { - ...transitionSpec, - toValue: 1, - }, - ), - ]; - - if (nextProps.navigationState.index !== this.props.navigationState.index) { - animations.push( - timing( - position, - { - ...transitionSpec, - toValue: nextProps.navigationState.index, - }, - ), - ); - } - - // update scenes and play the transition - this.setState(nextState, () => { - nextProps.onTransitionStart && nextProps.onTransitionStart( - this._transitionProps, - this._prevTransitionProps, - ); - Animated.parallel(animations).start(this._onTransitionEnd); - }); - } - - render(): React.Element { - return ( - - {this.props.render(this._transitionProps, this._prevTransitionProps)} - - ); - } - - _onLayout(event: any): void { - const {height, width} = event.nativeEvent.layout; - if (this.state.layout.initWidth === width && - this.state.layout.initHeight === height) { - return; - } - const layout = { - ...this.state.layout, - initHeight: height, - initWidth: width, - isMeasured: true, - }; - - layout.height.setValue(height); - layout.width.setValue(width); - - const nextState = { - ...this.state, - layout, - }; - - this._transitionProps = buildTransitionProps(this.props, nextState); - this.setState(nextState); - } - - _onTransitionEnd(): void { - if (!this._isMounted) { - return; - } - - const prevTransitionProps = this._prevTransitionProps; - this._prevTransitionProps = null; - - const nextState = { - ...this.state, - scenes: this.state.scenes.filter(isSceneNotStale), - }; - - this._transitionProps = buildTransitionProps(this.props, nextState); - - this.setState(nextState, () => { - this.props.onTransitionEnd && this.props.onTransitionEnd( - this._transitionProps, - prevTransitionProps, - ); - }); - } -} - -function buildTransitionProps( - props: Props, - state: State, -): NavigationTransitionProps { - const { - navigationState, - } = props; - - const { - layout, - position, - progress, - scenes, - } = state; - - const scene = scenes.find(isSceneActive); - - invariant(scene, 'No active scene when building navigation transition props.'); - - return { - layout, - navigationState, - position, - progress, - scenes, - scene - }; -} - -function isSceneNotStale(scene: NavigationScene): boolean { - return !scene.isStale; -} - -function isSceneActive(scene: NavigationScene): boolean { - return scene.isActive; -} - -const styles = StyleSheet.create({ - main: { - flex: 1, - }, -}); - -module.exports = NavigationTransitioner; diff --git a/Libraries/NavigationExperimental/NavigationTypeDefinition.js b/Libraries/NavigationExperimental/NavigationTypeDefinition.js deleted file mode 100644 index af37f9549..000000000 --- a/Libraries/NavigationExperimental/NavigationTypeDefinition.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationTypeDefinition - * @flow - */ -'use strict'; - -const Animated = require('Animated'); - -import type React from 'react'; - -// Object Instances - -export type NavigationAnimatedValue = Animated.Value; - -// Value & Structs. - -export type NavigationGestureDirection = 'horizontal' | 'vertical'; - -export type NavigationRoute = { - key: string, - title?: string -}; - -export type NavigationState = { - index: number, - routes: Array, -}; - -export type NavigationLayout = { - height: NavigationAnimatedValue, - initHeight: number, - initWidth: number, - isMeasured: boolean, - width: NavigationAnimatedValue, -}; - -export type NavigationScene = { - index: number, - isActive: boolean, - isStale: boolean, - key: string, - route: NavigationRoute, -}; - -export type NavigationTransitionProps = { - // The layout of the transitioner of the scenes. - layout: NavigationLayout, - - // The navigation state of the transitioner. - navigationState: NavigationState, - - // The progressive index of the transitioner's navigation state. - position: NavigationAnimatedValue, - - // The value that represents the progress of the transition when navigation - // state changes from one to another. Its numberic value will range from 0 - // to 1. - // progress.__getAnimatedValue() < 1 : transtion is happening. - // progress.__getAnimatedValue() == 1 : transtion completes. - progress: NavigationAnimatedValue, - - // All the scenes of the transitioner. - scenes: Array, - - // The active scene, corresponding to the route at - // `navigationState.routes[navigationState.index]`. - scene: NavigationScene, - - // The gesture distance for `horizontal` and `vertical` transitions - gestureResponseDistance?: ?number, -}; - -// Similar to `NavigationTransitionProps`, except that the prop `scene` -// represents the scene for the renderer to render. -export type NavigationSceneRendererProps = NavigationTransitionProps; - -export type NavigationPanPanHandlers = { - onMoveShouldSetResponder: Function, - onMoveShouldSetResponderCapture: Function, - onResponderEnd: Function, - onResponderGrant: Function, - onResponderMove: Function, - onResponderReject: Function, - onResponderRelease: Function, - onResponderStart: Function, - onResponderTerminate: Function, - onResponderTerminationRequest: Function, - onStartShouldSetResponder: Function, - onStartShouldSetResponderCapture: Function, -}; - -export type NavigationTransitionSpec = { - duration?: number, - // An easing function from `Easing`. - easing?: () => any, - // A timing function such as `Animated.timing`. - timing?: (value: NavigationAnimatedValue, config: any) => any, -}; - -// Functions. - -export type NavigationAnimationSetter = ( - position: NavigationAnimatedValue, - newState: NavigationState, - lastState: NavigationState, -) => void; - -export type NavigationSceneRenderer = ( - props: NavigationSceneRendererProps, -) => ?React.Element; - -export type NavigationStyleInterpolator = ( - props: NavigationSceneRendererProps, -) => Object; diff --git a/Libraries/NavigationExperimental/Reducer/NavigationScenesReducer.js b/Libraries/NavigationExperimental/Reducer/NavigationScenesReducer.js deleted file mode 100644 index 3bfd263f1..000000000 --- a/Libraries/NavigationExperimental/Reducer/NavigationScenesReducer.js +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule NavigationScenesReducer - * @flow - */ -'use strict'; - -const invariant = require('fbjs/lib/invariant'); -const shallowEqual = require('fbjs/lib/shallowEqual'); - -import type { - NavigationRoute, - NavigationScene, - NavigationState, -} from 'NavigationTypeDefinition'; - -const SCENE_KEY_PREFIX = 'scene_'; - -/** - * Helper function to compare route keys (e.g. "9", "11"). - */ -function compareKey(one: string, two: string): number { - const delta = one.length - two.length; - if (delta > 0) { - return 1; - } - if (delta < 0) { - return -1; - } - return one > two ? 1 : -1; -} - -/** - * Helper function to sort scenes based on their index and view key. - */ -function compareScenes( - one: NavigationScene, - two: NavigationScene, -): number { - if (one.index > two.index) { - return 1; - } - if (one.index < two.index) { - return -1; - } - - return compareKey( - one.key, - two.key, - ); -} - -/** - * Whether two routes are the same. - */ -function areScenesShallowEqual( - one: NavigationScene, - two: NavigationScene, -): boolean { - return ( - one.key === two.key && - one.index === two.index && - one.isStale === two.isStale && - one.isActive === two.isActive && - areRoutesShallowEqual(one.route, two.route) - ); -} - -/** - * Whether two routes are the same. - */ -function areRoutesShallowEqual( - one: ?NavigationRoute, - two: ?NavigationRoute, -): boolean { - if (!one || !two) { - return one === two; - } - - if (one.key !== two.key) { - return false; - } - - return shallowEqual(one, two); -} - -function NavigationScenesReducer( - scenes: Array, - nextState: NavigationState, - prevState: ?NavigationState, -): Array { - if (prevState === nextState) { - return scenes; - } - - const prevScenes: Map = new Map(); - const freshScenes: Map = new Map(); - const staleScenes: Map = new Map(); - - // Populate stale scenes from previous scenes marked as stale. - scenes.forEach(scene => { - const {key} = scene; - if (scene.isStale) { - staleScenes.set(key, scene); - } - prevScenes.set(key, scene); - }); - - const nextKeys = new Set(); - nextState.routes.forEach((route, index) => { - const key = SCENE_KEY_PREFIX + route.key; - const scene = { - index, - isActive: false, - isStale: false, - key, - route, - }; - invariant( - !nextKeys.has(key), - `navigationState.routes[${index}].key "${key}" conflicts with ` + - 'another route!' - ); - nextKeys.add(key); - - if (staleScenes.has(key)) { - // A previously `stale` scene is now part of the nextState, so we - // revive it by removing it from the stale scene map. - staleScenes.delete(key); - } - freshScenes.set(key, scene); - }); - - if (prevState) { - // Look at the previous routes and classify any removed scenes as `stale`. - prevState.routes.forEach((route: NavigationRoute, index) => { - const key = SCENE_KEY_PREFIX + route.key; - if (freshScenes.has(key)) { - return; - } - staleScenes.set(key, { - index, - isActive: false, - isStale: true, - key, - route, - }); - }); - } - - const nextScenes = []; - - const mergeScene = (nextScene => { - const {key} = nextScene; - const prevScene = prevScenes.has(key) ? prevScenes.get(key) : null; - if (prevScene && areScenesShallowEqual(prevScene, nextScene)) { - // Reuse `prevScene` as `scene` so view can avoid unnecessary re-render. - // This assumes that the scene's navigation state is immutable. - nextScenes.push(prevScene); - } else { - nextScenes.push(nextScene); - } - }); - - staleScenes.forEach(mergeScene); - freshScenes.forEach(mergeScene); - - nextScenes.sort(compareScenes); - - let activeScenesCount = 0; - nextScenes.forEach((scene, ii) => { - const isActive = !scene.isStale && scene.index === nextState.index; - if (isActive !== scene.isActive) { - nextScenes[ii] = { - ...scene, - isActive, - }; - } - if (isActive) { - activeScenesCount++; - } - }); - - invariant( - activeScenesCount === 1, - 'there should always be only one scene active, not %s.', - activeScenesCount, - ); - - if (nextScenes.length !== scenes.length) { - return nextScenes; - } - - if (nextScenes.some( - (scene, index) => !areScenesShallowEqual(scenes[index], scene) - )) { - return nextScenes; - } - - // scenes haven't changed. - return scenes; -} - -module.exports = NavigationScenesReducer; diff --git a/Libraries/NavigationExperimental/Reducer/__tests__/NavigationScenesReducer-test.js b/Libraries/NavigationExperimental/Reducer/__tests__/NavigationScenesReducer-test.js deleted file mode 100644 index 8d320337c..000000000 --- a/Libraries/NavigationExperimental/Reducer/__tests__/NavigationScenesReducer-test.js +++ /dev/null @@ -1,300 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ -'use strict'; - -jest.unmock('NavigationScenesReducer'); - -const NavigationScenesReducer = require('NavigationScenesReducer'); - -/** - * Simulate scenes transtion with changes of navigation states. - */ -function testTransition(states) { - const routes = states.map(keys => { - return { - index: 0, - routes: keys.map(key => { - return { key }; - }), - }; - }); - - let scenes = []; - let prevState = null; - routes.forEach((nextState) => { - scenes = NavigationScenesReducer(scenes, nextState, prevState); - prevState = nextState; - }); - - return scenes; -} - -describe('NavigationScenesReducer', () => { - - it('gets initial scenes', () => { - const scenes = testTransition([ - ['1', '2'], - ]); - - expect(scenes).toEqual([ - { - index: 0, - isActive: true, - isStale: false, - key: 'scene_1', - route: { - key: '1' - }, - }, - { - index: 1, - isActive: false, - isStale: false, - key: 'scene_2', - route: { - key: '2' - }, - }, - ]); - }); - - it('pushes new scenes', () => { - // Transition from ['1', '2'] to ['1', '2', '3']. - const scenes = testTransition([ - ['1', '2'], - ['1', '2', '3'], - ]); - - expect(scenes).toEqual([ - { - index: 0, - isActive: true, - isStale: false, - key: 'scene_1', - route: { - key: '1' - }, - }, - { - index: 1, - isActive: false, - isStale: false, - key: 'scene_2', - route: { - key: '2' - }, - }, - { - index: 2, - isActive: false, - isStale: false, - key: 'scene_3', - route: { - key: '3' - }, - }, - ]); - }); - - it('gets active scene when index changes', () => { - const state1 = { - index: 0, - routes: [{key: '1'}, {key: '2'}], - }; - - const state2 = { - index: 1, - routes: [{key: '1'}, {key: '2'}], - }; - - const scenes1 = NavigationScenesReducer([], state1, null); - const scenes2 = NavigationScenesReducer(scenes1, state2, state1); - const route = scenes2.find((scene) => scene.isActive).route; - expect(route).toEqual({key: '2'}); - }); - - it('gets same scenes', () => { - const state1 = { - index: 0, - routes: [{key: '1'}, {key: '2'}], - }; - - const state2 = { - index: 0, - routes: [{key: '1'}, {key: '2'}], - }; - - const scenes1 = NavigationScenesReducer([], state1, null); - const scenes2 = NavigationScenesReducer(scenes1, state2, state1); - expect(scenes1).toBe(scenes2); - }); - - it('gets different scenes when keys are different', () => { - const state1 = { - index: 0, - routes: [{key: '1'}, {key: '2'}], - }; - - const state2 = { - index: 0, - routes: [{key: '2'}, {key: '1'}], - }; - - const scenes1 = NavigationScenesReducer([], state1, null); - const scenes2 = NavigationScenesReducer(scenes1, state2, state1); - expect(scenes1).not.toBe(scenes2); - }); - - it('gets different scenes when routes are different', () => { - const state1 = { - index: 0, - routes: [{key: '1', x: 1}, {key: '2', x: 2}], - }; - - const state2 = { - index: 0, - routes: [{key: '1', x: 3}, {key: '2', x: 4}], - }; - - const scenes1 = NavigationScenesReducer([], state1, null); - const scenes2 = NavigationScenesReducer(scenes1, state2, state1); - expect(scenes1).not.toBe(scenes2); - }); - - - it('gets different scenes when state index changes', () => { - const state1 = { - index: 0, - routes: [{key: '1', x: 1}, {key: '2', x: 2}], - }; - - const state2 = { - index: 1, - routes: [{key: '1', x: 1}, {key: '2', x: 2}], - }; - - const scenes1 = NavigationScenesReducer([], state1, null); - const scenes2 = NavigationScenesReducer(scenes1, state2, state1); - expect(scenes1).not.toBe(scenes2); - }); - - it('pops scenes', () => { - // Transition from ['1', '2', '3'] to ['1', '2']. - const scenes = testTransition([ - ['1', '2', '3'], - ['1', '2'], - ]); - - expect(scenes).toEqual([ - { - index: 0, - isActive: true, - isStale: false, - key: 'scene_1', - route: { - key: '1' - }, - }, - { - index: 1, - isActive: false, - isStale: false, - key: 'scene_2', - route: { - key: '2' - }, - }, - { - index: 2, - isActive: false, - isStale: true, - key: 'scene_3', - route: { - key: '3' - }, - }, - ]); - }); - - it('replaces scenes', () => { - const scenes = testTransition([ - ['1', '2'], - ['3'], - ]); - - expect(scenes).toEqual([ - { - index: 0, - isActive: false, - isStale: true, - key: 'scene_1', - route: { - key: '1' - }, - }, - { - index: 0, - isActive: true, - isStale: false, - key: 'scene_3', - route: { - key: '3' - }, - }, - { - index: 1, - isActive: false, - isStale: true, - key: 'scene_2', - route: { - key: '2' - }, - }, - ]); - }); - - it('revives scenes', () => { - const scenes = testTransition([ - ['1', '2'], - ['3'], - ['2'], - ]); - - expect(scenes).toEqual([ - { - index: 0, - isActive: false, - isStale: true, - key: 'scene_1', - route: { - key: '1' - }, - }, - { - index: 0, - isActive: true, - isStale: false, - key: 'scene_2', - route: { - key: '2' - }, - }, - { - index: 0, - isActive: false, - isStale: true, - key: 'scene_3', - route: { - key: '3' - }, - }, - ]); - }); -}); diff --git a/Libraries/NavigationExperimental/__tests__/NavigationStateUtils-test.js b/Libraries/NavigationExperimental/__tests__/NavigationStateUtils-test.js deleted file mode 100644 index d71d88800..000000000 --- a/Libraries/NavigationExperimental/__tests__/NavigationStateUtils-test.js +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -'use strict'; - -jest.unmock('NavigationStateUtils'); - -const NavigationStateUtils = require('NavigationStateUtils'); - -describe('NavigationStateUtils', () => { - - // Getters - it('gets route', () => { - const state = {index: 0, routes: [{key: 'a'}]}; - expect(NavigationStateUtils.get(state, 'a')).toEqual({key: 'a'}); - expect(NavigationStateUtils.get(state, 'b')).toBe(null); - }); - - it('gets route index', () => { - const state = {index: 1, routes: [{key: 'a'}, {key: 'b'}]}; - expect(NavigationStateUtils.indexOf(state, 'a')).toBe(0); - expect(NavigationStateUtils.indexOf(state, 'b')).toBe(1); - expect(NavigationStateUtils.indexOf(state, 'c')).toBe(-1); - }); - - it('has a route', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - expect(NavigationStateUtils.has(state, 'b')).toBe(true); - expect(NavigationStateUtils.has(state, 'c')).toBe(false); - }); - - // Push - it('pushes a route', () => { - const state = {index: 0, routes: [{key: 'a'}]}; - const newState = {index: 1, routes: [{key: 'a'}, {key: 'b'}]}; - expect(NavigationStateUtils.push(state, {key: 'b'})).toEqual(newState); - }); - - it('does not push duplicated route', () => { - const state = {index: 0, routes: [{key: 'a'}]}; - expect(() => NavigationStateUtils.push(state, {key: 'a'})).toThrow(); - }); - - // Pop - it('pops route', () => { - const state = {index: 1, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 0, routes: [{key: 'a'}]}; - expect(NavigationStateUtils.pop(state)).toEqual(newState); - }); - - it('does not pop route if not applicable', () => { - const state = {index: 0, routes: [{key: 'a'}]}; - expect(NavigationStateUtils.pop(state)).toBe(state); - }); - - // Jump - it('jumps to new index', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 1, routes: [{key: 'a'}, {key: 'b'}]}; - expect(NavigationStateUtils.jumpToIndex(state, 0)).toBe(state); - expect(NavigationStateUtils.jumpToIndex(state, 1)).toEqual(newState); - }); - - it('throws if jumps to invalid index', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - expect(() => NavigationStateUtils.jumpToIndex(state, 2)).toThrow(); - }); - - it('jumps to new key', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 1, routes: [{key: 'a'}, {key: 'b'}]}; - expect(NavigationStateUtils.jumpTo(state, 'a')).toBe(state); - expect(NavigationStateUtils.jumpTo(state, 'b')).toEqual(newState); - }); - - it('throws if jumps to invalid key', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - expect(() => NavigationStateUtils.jumpTo(state, 'c')).toThrow(); - }); - - it('move backwards', () => { - const state = {index: 1, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - expect(NavigationStateUtils.back(state)).toEqual(newState); - expect(NavigationStateUtils.back(newState)).toBe(newState); - }); - - it('move forwards', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 1, routes: [{key: 'a'}, {key: 'b'}]}; - expect(NavigationStateUtils.forward(state)).toEqual(newState); - expect(NavigationStateUtils.forward(newState)).toBe(newState); - }); - - // Replace - it('Replaces by key', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 1, routes: [{key: 'a'}, {key: 'c'}]}; - expect( - NavigationStateUtils.replaceAt( - state, - 'b', - {key: 'c'}, - ) - ).toEqual(newState); - }); - - it('Replaces by index', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 1, routes: [{key: 'a'}, {key: 'c'}]}; - expect( - NavigationStateUtils.replaceAtIndex( - state, - 1, - {key: 'c'}, - ) - ).toEqual(newState); - }); - - // Reset - it('Resets routes', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 1, routes: [{key: 'x'}, {key: 'y'}]}; - expect( - NavigationStateUtils.reset( - state, - [{key: 'x'}, {key: 'y'}], - ) - ).toEqual(newState); - - expect(() => { - NavigationStateUtils.reset(state, []); - }).toThrow(); - }); - - it('Resets routes with index', () => { - const state = {index: 0, routes: [{key: 'a'}, {key: 'b'}]}; - const newState = {index: 0, routes: [{key: 'x'}, {key: 'y'}]}; - expect( - NavigationStateUtils.reset( - state, - [{key: 'x'}, {key: 'y'}], - 0, - ) - ).toEqual(newState); - - expect(() => { - NavigationStateUtils.reset(state, [{key: 'x'}, {key: 'y'}], 100); - }).toThrow(); - }); -}); diff --git a/Libraries/react-native/react-native-implementation.js b/Libraries/react-native/react-native-implementation.js index b0e86440b..5296fe3cf 100644 --- a/Libraries/react-native/react-native-implementation.js +++ b/Libraries/react-native/react-native-implementation.js @@ -95,7 +95,6 @@ const ReactNative = { get LayoutAnimation() { return require('LayoutAnimation'); }, get Linking() { return require('Linking'); }, get NativeEventEmitter() { return require('NativeEventEmitter'); }, - get NavigationExperimental() { return require('NavigationExperimental'); }, get NetInfo() { return require('NetInfo'); }, get PanResponder() { return require('PanResponder'); }, get PermissionsAndroid() { return require('PermissionsAndroid'); },