From d9649a2943cb9417ba7e27d865f79fc96eca72b0 Mon Sep 17 00:00:00 2001 From: James Ide Date: Tue, 20 Dec 2016 11:07:44 +0000 Subject: [PATCH 01/12] Rename exponentjs references in our libraries fbshipit-source-id: 21072ac --- README.md | 4 ++-- example-shared-element-transitions/package.json | 2 +- example/exp.json | 2 +- example/package.json | 2 +- package.json | 4 ++-- src/ExUnsupportedNativeView.js | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2c285c2..835b74b 100644 --- a/README.md +++ b/README.md @@ -472,7 +472,7 @@ class TabScreen extends React.Component { ``` See an example of TabNavigation in a real app -[here](https://github.com/exponentjs/rnplay/blob/f4d29c4578fb57347afd0d507a036dd232ec6fdb/navigation/TabNavigationLayout.js). +[here](https://github.com/exponent/rnplay/blob/f4d29c4578fb57347afd0d507a036dd232ec6fdb/navigation/TabNavigationLayout.js). If you'd like to switch tabs programmatically (eg: a notification arrives and you want to jump to a notifications tab, or you tap on a @@ -652,7 +652,7 @@ export const Router = createRouter(() => ({ ### Perform navigation actions from outside of a component You might be using some Redux middleware like saga, thunk, promise, or -effex (we recommend [effex](https://github.com/exponentjs/redux-effex) +effex (we recommend [effex](https://github.com/exponent/redux-effex) because we love `async/await`). Whatever you're using, you no longer have access to `this.props.navigator` and the like. What to do? Well as long as you include your navigation state inside of your Redux diff --git a/example-shared-element-transitions/package.json b/example-shared-element-transitions/package.json index 9dedbb0..eb4c648 100644 --- a/example-shared-element-transitions/package.json +++ b/example-shared-element-transitions/package.json @@ -8,6 +8,6 @@ "exponent": "~11.0.2", "lodash": "^4.13.1", "react": "~15.3.2", - "react-native": "git+https://github.com/exponentjs/react-native#sdk-11.0.3" + "react-native": "git+https://github.com/exponent/react-native#sdk-11.0.3" } } diff --git a/example/exp.json b/example/exp.json index e938de1..92a9a64 100644 --- a/example/exp.json +++ b/example/exp.json @@ -1,6 +1,6 @@ { name: "ExNavigationExample", - description: "Demonstrate usage of ex-navigation: https://github.com/exponentjs/ex-navigation", + description: "Demonstrate usage of ex-navigation: https://github.com/exponent/ex-navigation", slug: "ex-navigation-example", sdkVersion: "12.0.0", version: "1.0.0", diff --git a/example/package.json b/example/package.json index 372a1c9..36723b4 100644 --- a/example/package.json +++ b/example/package.json @@ -9,6 +9,6 @@ "exponent": "~12.0.3", "lodash": "^4.13.1", "react": "~15.3.2", - "react-native": "git+https://github.com/exponentjs/react-native#sdk-12.0.0" + "react-native": "git+https://github.com/exponent/react-native#sdk-12.0.0" } } diff --git a/package.json b/package.json index d18c44b..abfc8f5 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "lint": "eslint ./src ./example", "test": "echo \"Error: no test specified\" && exit 1" }, - "repository": "https://github.com/exponentjs/ex-navigation.git", + "repository": "https://github.com/exponent/ex-navigation.git", "keywords": [ "react-native", "navigation", @@ -54,6 +54,6 @@ "eslint-plugin-react": "^5.2.2", "flow-bin": "^0.30.0", "react": "15.3.2", - "react-native": "git+https://github.com/exponentjs/react-native#exp-latest" + "react-native": "git+https://github.com/exponent/react-native#exp-latest" } } diff --git a/src/ExUnsupportedNativeView.js b/src/ExUnsupportedNativeView.js index 32af5be..8fd54bd 100644 --- a/src/ExUnsupportedNativeView.js +++ b/src/ExUnsupportedNativeView.js @@ -11,7 +11,7 @@ export function unsupportedNativeView(name) { componentWillMount() { if (__DEV__) { console.log(`Attempted to use native ${name}, this isn't supported outside of Exponent`); - console.log(`If you would like to make it work, submit a PR to: https://github.com/exponentjs/ex-navigation`); + console.log(`If you would like to make it work, submit a PR to: https://github.com/exponent/ex-navigation`); console.log(`If you are using Exponent, make sure that you have imported the \`exponent\` module in your app`); } } From 3cd8247f61e1a31badc5242660d1803577d05644 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 21 Dec 2016 23:10:50 +0000 Subject: [PATCH 02/12] Add note about future and support fbshipit-source-id: deaf920 --- README.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 835b74b..3d4c850 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,30 @@ support](https://img.shields.io/badge/exponent-ios%20%7C%20android-blue.svg?styl A route-centric, batteries-included navigation library for Exponent and React Native that works seamlessly on Android and iOS. -### A few of our favorite features: +### READ THIS: An important note about the future + +"ExNavigation 2" will be called "react-navigation" and it will live on +the [reactjs](https://github.com/reactjs) organization. It is currently +being built and scheduled for a beta release in January, 2017. A +migration path from ExNavigation will be provided. + +This means that ExNavigation is currently in maintenance mode -- we +aren't actively adding new features unless we need them for our own +projects, because further work is being directed towards +react-navigation. Pull requests are still welcome. + +## Help / Support / Questions + +We don't provide any realtime support for ExNavigation questions. If you +join the Exponent Slack and ask a question there, we will direct you to +this section of the README. We suggest the following resources: + +- Search the README. +- [Search the issues, then post an issue if nothing matches](https://github.com/exponent/ex-navigation/issues). +- Search the code if nothing else works. +- Once you solve your problem, submit a pull request to add the solution to the README. + +### A few of our favorite features - Android back button handling (it just works, no need to do anything) - Tab bar navigation From 5cd3bec72fa2a852bcf09b5377676540b4e39a3f Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 21 Dec 2016 23:24:26 +0000 Subject: [PATCH 03/12] Update README heading formatting fbshipit-source-id: 749daf6 --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3d4c850..531eb92 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,18 @@ support](https://img.shields.io/badge/exponent-ios%20%7C%20android-blue.svg?styl A route-centric, batteries-included navigation library for Exponent and React Native that works seamlessly on Android and iOS. -### READ THIS: An important note about the future +### A few of our favorite features + +- Android back button handling (it just works, no need to do anything) +- Tab bar navigation +- Drawer navigation +- Sliding tab navigation +- Optional blurred translucent backgrounds in navigation and tab bar on iOS +- Alert bars +- Declarative configuration co-located with your routes +- Typed with Flow + +## An important note about the future "ExNavigation 2" will be called "react-navigation" and it will live on the [reactjs](https://github.com/reactjs) organization. It is currently @@ -31,17 +42,6 @@ this section of the README. We suggest the following resources: - Search the code if nothing else works. - Once you solve your problem, submit a pull request to add the solution to the README. -### A few of our favorite features - -- Android back button handling (it just works, no need to do anything) -- Tab bar navigation -- Drawer navigation -- Sliding tab navigation -- Optional blurred translucent backgrounds in navigation and tab bar on iOS -- Alert bars -- Declarative configuration co-located with your routes -- Typed with Flow - ## Installation As of version 1.9.0, ExNavigation only supports React Native versions >= From 902a12779759718999fc4a02d8e088b70d61ba60 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Fri, 23 Dec 2016 19:02:43 +0000 Subject: [PATCH 04/12] Use measure instead of measureInWindow to avoid position bug with translucent status bar on Android There'\''s a bug with in RN with translucent statusbar because it always adds the statusbar height. This uses instead with does pretty much the same thing but doesn'\''t have that bug (it'\''s actually the proper way to do it since it measures relative to the root view). Fixes #320 Closes exponent/ex-navigation#321 fbshipit-source-id: 5a4d554 --- src/shared-element/ExNavigationSharedElement.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared-element/ExNavigationSharedElement.js b/src/shared-element/ExNavigationSharedElement.js index fa70004..a6e0c65 100644 --- a/src/shared-element/ExNavigationSharedElement.js +++ b/src/shared-element/ExNavigationSharedElement.js @@ -106,9 +106,9 @@ export default class SharedElement extends Component { return; } - UIManager.measureInWindow( + UIManager.measure( findNodeHandle(this._el), - (x, y, width, height) => { + (origX, origY, width, height, x, y) => { const store = this.context.sharedElementStore; store.dispatch({ type: 'UPDATE_METRICS_FOR_ELEMENT', From 54a85a49b4a3534c0c90f68101a5fa9d19c86c5d Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Fri, 23 Dec 2016 19:02:53 +0000 Subject: [PATCH 05/12] android back button handling in readme skevy agreed with how I responded here https://github.com/exponent/ex-navigation/issues/99 and this is based on that. Closes exponent/ex-navigation#332 fbshipit-source-id: 292757b --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 531eb92..e234208 100644 --- a/README.md +++ b/README.md @@ -735,3 +735,19 @@ const screenTracking = ({ getState }) => next => action => { export default screenTracking; ``` + +### Android back button handling + +React Native includes a global `BackAndroid` module. Rather than using this module +directly, include the `AndroidBackButtonBehavior` component in routes where you'd +like to control the back button. `AndroidBackButtonBehavior` accepts +`isFocused` and `onBackButtonPress`. If `isFocused` is true, the `onBackButtonPress` +will fire when the user presses the back button. You need to make sure that `onBackButtonPress` +returns a promise that wraps the function you want to be called. Eg. + +``` +Promise.resolve(fireMeWhenSomeBooleanIsTrue)}> + ... + +``` From d371be1f34caa4656a5ecbd4960adba8ffaa6241 Mon Sep 17 00:00:00 2001 From: Ali Roberts Date: Fri, 23 Dec 2016 19:05:01 +0000 Subject: [PATCH 06/12] Added onWillChangeTab prop to tab A hook for when a tab change has been triggered. The tab change will proceed if the function'\''s return value is true, and will be cancelled if it is false. Closes exponent/ex-navigation#274 fbshipit-source-id: 0929933 --- src/tab/ExNavigationTab.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tab/ExNavigationTab.js b/src/tab/ExNavigationTab.js index 4fac70b..be241fd 100644 --- a/src/tab/ExNavigationTab.js +++ b/src/tab/ExNavigationTab.js @@ -56,7 +56,7 @@ export class ExNavigationTabContext extends ExNavigatorContext { type TabItem = { id: string, renderIcon?: Function, - renderBadge?: Function, + renderBadge?: Function, tabContent?: React.Element<{}>, }; @@ -72,6 +72,7 @@ type Props = { navigation: ExNavigationContext, onRegisterNavigatorContext: (navigatorUID: string, navigatorContext: ExNavigationTabContext) => void, onUnregisterNavigatorContext: (navigatorUID: string) => void, + onWillChangeTab: (id: string) => bool, navigationState: Object, translucent?: bool, }; @@ -312,6 +313,13 @@ class ExNavigationTab extends PureComponent { } _setActiveTab(id, index) { + if (typeof this.props.onWillChangeTab === 'function') { + let changeTab = this.props.onWillChangeTab(id); + if (!changeTab) { + return; + } + } + this._getNavigatorContext().jumpToTab(id); if (typeof this.props.onTabPress === 'function') { this.props.onTabPress(id); From 9be9cb918761ce62d24d39a82322ee47bb5d391b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Dar=C3=ADo?= Date: Fri, 23 Dec 2016 19:06:31 +0000 Subject: [PATCH 07/12] Allows to specify alert duration Specify duration in milliseconds through its options, as the other props. E.g (using redux) Enhances https://github.com/exponentjs/ex-navigation/issues/53 Closes exponent/ex-navigation#241 fbshipit-source-id: 71c7df8 --- src/ExNavigationAlertBar.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ExNavigationAlertBar.js b/src/ExNavigationAlertBar.js index d419914..488cd2a 100644 --- a/src/ExNavigationAlertBar.js +++ b/src/ExNavigationAlertBar.js @@ -130,11 +130,15 @@ export default class ExNavigationAlertBar extends React.Component { } _show = () => { + const { currentAlertState } = this.state; + const { options } = currentAlertState + const duration = options.duration || ALERT_DISPLAY_TIME_MS + this.setState({isVisible: true}, () => { this.requestAnimationFrame(() => { this._textContainerRef && this._textContainerRef.measure((l, t, w, height) => { this._animateIn(height); - this._timeout = this.setTimeout(this._dispatchHide, ALERT_DISPLAY_TIME_MS); + this._timeout = this.setTimeout(this._dispatchHide, duration); }); }); }); From 6b1f83adadac6a77171f356b28fd046b0af4c901 Mon Sep 17 00:00:00 2001 From: jewel mlnarik Date: Fri, 23 Dec 2016 19:08:17 +0000 Subject: [PATCH 08/12] New Style for Horizontal with NoAnimation in NavBar This came from a need to not have the navbar flash when screens were transitioning, due to the navbar being rather static (think Facebook'\''s search bar). It'\''s possible this is a config or param setting I over-looked ... and if others want this, could see expanding this to allow navbar animation to be set separately or toggled off independently from the screen transition. In the spirit of keeping it simple, this simply creates a new style one can pass in that does not set any transition/fade/animation for the navbar while allowing the rest of the screen to animate in the traditional fashion. Closes exponent/ex-navigation#243 fbshipit-source-id: 74791b8 --- src/ExNavigationStyles.js | 90 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/ExNavigationStyles.js b/src/ExNavigationStyles.js index 57a833a..34980a1 100644 --- a/src/ExNavigationStyles.js +++ b/src/ExNavigationStyles.js @@ -205,6 +205,96 @@ export const SlideHorizontalIOS: ExNavigationStyles = { gestures: CardStackPanResponder.forHorizontal, }; + +export const SlideHorizontalFixedNav: ExNavigationStyles = { + configureTransition: configureSpringTransition, + sceneAnimations: customForHorizontal, + navigationBarAnimations: { + forContainer: (props, delta) => { + const { + layout, + position, + scene, + scenes, + } = props; + + const index = scene.index; + + const meVisible = barVisibleForSceneIndex(scenes, index); + let offset = layout.initWidth; + if (delta === 0) { + // default state + offset = meVisible ? offset : -offset; + } else { + // if we're pushing, get the previous scenes' visibility. If we're popping, get the scene ahead + const prevVisible = barVisibleForSceneIndex(scenes, index + (delta > 0 ? -1 : 1)); + if (!prevVisible && meVisible) { + // when showing, if a push, move from right to left, otherwise if pop, move from left to right + offset = delta > 0 ? offset : -offset; + } else { + // when hiding, if a push, move from left to right, otherwise if a pop, move from right to left + offset = delta > 0 ? -offset : offset; + } + } + + return { + transform: [ + { + translateX: position.interpolate({ + inputRange: [index - 1, index, index + 1], + outputRange: [ + barVisibleForSceneIndex(scenes, index - 1) ? 0 : offset, + barVisibleForSceneIndex(scenes, index) ? 0 : offset, + barVisibleForSceneIndex(scenes, index + 1) ? 0 : offset, + ], + }), + }, + ], + }; + }, + /** + * Crossfade the left view + */ + forLeft: (props) => { + const {position, scene, scenes} = props; + const {index} = scene; + return { + opacity: position.interpolate({ + inputRange: [index - 1, index, index + 1], + outputRange: [0, barVisibleForSceneIndex(scenes, index) ? 1 : 0, 0], + }), + }; + }, + /** + * Crossfade the title + */ + forCenter: (props) => { + const {position, scene, scenes} = props; + const {index} = scene; + return { + opacity: position.interpolate({ + inputRange: [index - 1, index, index + 1], + outputRange: [0, barVisibleForSceneIndex(scenes, index) ? 1 : 0, 0], + }), + }; + }, + /** + * Crossfade the right view + */ + forRight: (props) => { + const {position, scene, scenes} = props; + const {index} = scene; + return { + opacity: position.interpolate({ + inputRange: [index - 1, index, index + 1], + outputRange: [0, barVisibleForSceneIndex(scenes, index) ? 1 : 0, 0], + }), + }; + }, + gestures: CardStackPanResponder.forHorizontal, + } +}; + export const SlideHorizontal: ExNavigationStyles = { configureTransition: configureSpringTransition, sceneAnimations: customForHorizontal, From a046a52cac950077154664317826c9860c7f747b Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Fri, 23 Dec 2016 19:38:03 +0000 Subject: [PATCH 09/12] Bump to 2.5.0 fbshipit-source-id: abf0c1f --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index abfc8f5..e36f2de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exponent/ex-navigation", - "version": "2.4.0", + "version": "2.5.0", "description": "Route-centric navigation library for React Native.", "main": "./src/ExNavigation.js", "files": [ From a1d0e9ae8798b8a8bca2bc49951fd9d897762e57 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Fri, 23 Dec 2016 19:42:39 +0000 Subject: [PATCH 10/12] Fix example drawer header fbshipit-source-id: 0c7bd0f --- example/components/DrawerNavigationExample.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/example/components/DrawerNavigationExample.js b/example/components/DrawerNavigationExample.js index 69d92fd..033a1ca 100644 --- a/example/components/DrawerNavigationExample.js +++ b/example/components/DrawerNavigationExample.js @@ -16,7 +16,11 @@ import { Router } from '../main'; export default class DrawerNavigationExample extends Component { _renderHeader = () => { - return ; + return ( + + + + ); }; _renderTitle = (text: string, isSelected: bool) => { From 5935a4f2dff38f6b500992aff6fef647025c10f9 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Sun, 25 Dec 2016 20:00:16 +0000 Subject: [PATCH 11/12] Update tab-view dep, add getRenderLabel fn, bump version fbshipit-source-id: 47ab35b --- package.json | 4 ++-- src/sliding-tab/ExNavigationSlidingTab.js | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e36f2de..56a7e92 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exponent/ex-navigation", - "version": "2.5.0", + "version": "2.6.0", "description": "Route-centric navigation library for React Native.", "main": "./src/ExNavigation.js", "files": [ @@ -35,7 +35,7 @@ "react-clone-referenced-element": "^1.0.1", "react-mixin": "^3.0.5", "react-native-drawer-layout": "^1.0.0", - "react-native-tab-view": "^0.0.38", + "react-native-tab-view": "0.0.42", "react-redux": "^4.4.5", "react-static-container": "^1.0.0", "react-timer-mixin": "^0.13.3", diff --git a/src/sliding-tab/ExNavigationSlidingTab.js b/src/sliding-tab/ExNavigationSlidingTab.js index 0179e1c..3218788 100644 --- a/src/sliding-tab/ExNavigationSlidingTab.js +++ b/src/sliding-tab/ExNavigationSlidingTab.js @@ -6,6 +6,7 @@ import React, { Children, } from 'react'; import { + Platform, StyleSheet, View, } from 'react-native'; @@ -20,11 +21,15 @@ import ExNavigatorContext from '../ExNavigatorContext'; import ExNavigationBar from '../ExNavigationBar'; import ExNavigationSlidingTabItem from './ExNavigationSlidingTabItem'; import { ExNavigationTabContext } from '../tab/ExNavigationTab'; -import { TabViewAnimated, TabViewPagerPan, TabBarTop, TabBar } from 'react-native-tab-view'; +import { TabViewAnimated, TabViewPagerAndroid, TabViewPagerScroll, TabBarTop, TabBar } from 'react-native-tab-view'; import { createNavigatorComponent } from '../ExNavigationComponents'; import type ExNavigationContext from '../ExNavigationContext'; +const TabViewPagerComponent = Platform.OS === 'ios' ? + TabViewPagerScroll : + TabViewPagerAndroid; + // TODO: Fill this in type SlidingTabItem = { id: string, @@ -49,6 +54,7 @@ type Props = { renderHeader?: (props: any) => ?React.Element, renderFooter?: (props: any) => ?React.Element, renderLabel?: (routeParams: any) => ?React.Element, + getRenderLabel?: (props: any) => (routeParams: any) => ?React.Element, style?: any, swipeEnabled?: boolean, tabBarStyle?: any, @@ -192,7 +198,7 @@ class ExNavigationSlidingTab extends PureComponent { _renderPager = (props) => { return ( - @@ -210,12 +216,16 @@ class ExNavigationSlidingTab extends PureComponent { _renderTabBar = (props) => { const TabBarComponent = this.props.position === 'top' ? TabBarTop : TabBar; + const renderLabelFn = this.props.getRenderLabel ? + this.props.getRenderLabel(props) : + this.props.renderLabel; + const tabBarProps = { pressColor: this.props.pressColor, indicatorStyle: this.props.indicatorStyle, tabStyle: this.props.tabStyle, labelStyle: this.props.labelStyle, - renderLabel: this.props.renderLabel, + renderLabel: renderLabelFn, style: [{backgroundColor: this.props.barBackgroundColor}, this.props.tabBarStyle], }; From 71c960a4ba1ccb6f89062d35325a1262ff7ff9f6 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 28 Dec 2016 19:09:28 +0000 Subject: [PATCH 12/12] Factor in navbar height option fbshipit-source-id: bf7d5d4 --- package.json | 2 +- src/ExNavigationStack.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 56a7e92..5aa46ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exponent/ex-navigation", - "version": "2.6.0", + "version": "2.7.0", "description": "Route-centric navigation library for React Native.", "main": "./src/ExNavigation.js", "files": [ diff --git a/src/ExNavigationStack.js b/src/ExNavigationStack.js index 5994e01..90530b9 100644 --- a/src/ExNavigationStack.js +++ b/src/ExNavigationStack.js @@ -471,9 +471,13 @@ class ExNavigationStack extends PureComponent { _getNavigationBarHeight(latestRouteConfig) { let height = NavigationBar.DEFAULT_HEIGHT; + if (latestRouteConfig.navigationBar && latestRouteConfig.navigationBar.height) { + height = latestRouteConfig.navigationBar.height + DEFAULT_STATUSBAR_HEIGHT; + } + if (latestRouteConfig.statusBar && latestRouteConfig.statusBar.translucent) { height = NavigationBar.DEFAULT_HEIGHT_WITHOUT_STATUS_BAR + DEFAULT_STATUSBAR_HEIGHT; - }; + } return height; }