Skip to content
This repository has been archived by the owner on Feb 15, 2019. It is now read-only.

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
John Clema authored Jan 2, 2017
2 parents ccfe727 + 71c960a commit 0a5b8f3
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 20 deletions.
45 changes: 42 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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:
### A few of our favorite features

- Android back button handling (it just works, no need to do anything)
- Tab bar navigation
Expand All @@ -19,6 +19,29 @@ React Native that works seamlessly on Android and iOS.
- 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
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.

## Installation

As of version 1.9.0, ExNavigation only supports React Native versions >=
Expand Down Expand Up @@ -472,7 +495,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
Expand Down Expand Up @@ -652,7 +675,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
Expand Down Expand Up @@ -712,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.

```
<AndroidBackButtonBehavior isFocused={someboolean}
onBackButtonPress={()=>Promise.resolve(fireMeWhenSomeBooleanIsTrue)}>
...
</AndroidBackButtonBehavior>
```
2 changes: 1 addition & 1 deletion example-shared-element-transitions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
6 changes: 5 additions & 1 deletion example/components/DrawerNavigationExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import { Router } from '../main';
export default class DrawerNavigationExample extends Component {

_renderHeader = () => {
return <Image source={require('../assets/sparkles.jpg')} style={styles.header} />;
return (
<View style={{height: 180, width: 300}}>
<Image source={require('../assets/sparkles.jpg')} style={styles.header} />
</View>
);
};

_renderTitle = (text: string, isSelected: bool) => {
Expand Down
2 changes: 1 addition & 1 deletion example/exp.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@exponent/ex-navigation",
"version": "2.4.0",
"version": "2.7.0",
"description": "Route-centric navigation library for React Native.",
"main": "./src/ExNavigation.js",
"files": [
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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"
}
}
6 changes: 5 additions & 1 deletion src/ExNavigationAlertBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
});
Expand Down
6 changes: 5 additions & 1 deletion src/ExNavigationStack.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,9 +471,13 @@ class ExNavigationStack extends PureComponent<any, Props, State> {
_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;
}
Expand Down
90 changes: 90 additions & 0 deletions src/ExNavigationStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/ExUnsupportedNativeView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/shared-element/ExNavigationSharedElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
16 changes: 13 additions & 3 deletions src/sliding-tab/ExNavigationSlidingTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React, {
Children,
} from 'react';
import {
Platform,
StyleSheet,
View,
} from 'react-native';
Expand All @@ -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,
Expand All @@ -51,6 +56,7 @@ type Props = {
renderHeader?: (props: any) => ?React.Element<any>,
renderFooter?: (props: any) => ?React.Element<any>,
renderLabel?: (routeParams: any) => ?React.Element<any>,
getRenderLabel?: (props: any) => (routeParams: any) => ?React.Element<any>,
style?: any,
swipeEnabled?: boolean,
tabBarStyle?: any,
Expand Down Expand Up @@ -194,7 +200,7 @@ class ExNavigationSlidingTab extends PureComponent<any, Props, State> {

_renderPager = (props) => {
return (
<TabViewPagerPan
<TabViewPagerComponent
{...props}
swipeEnabled={this.props.swipeEnabled}
/>
Expand All @@ -212,14 +218,18 @@ class ExNavigationSlidingTab extends PureComponent<any, Props, State> {

_renderTabBar = (props) => {
const TabBarComponent = this.props.position === 'top' ? TabBarTop : TabBar;
const renderLabelFn = this.props.getRenderLabel ?
this.props.getRenderLabel(props) :
this.props.renderLabel;

const tabBarProps = {
scrollEnabled: this.props.scrollEnabled,
tabWidth: this.props.tabWidth,
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],
};

Expand Down
10 changes: 9 additions & 1 deletion src/tab/ExNavigationTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class ExNavigationTabContext extends ExNavigatorContext {
type TabItem = {
id: string,
renderIcon?: Function,
renderBadge?: Function,
renderBadge?: Function,
tabContent?: React.Element<{}>,
};

Expand All @@ -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,
};
Expand Down Expand Up @@ -312,6 +313,13 @@ class ExNavigationTab extends PureComponent<any, Props, State> {
}

_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);
Expand Down

0 comments on commit 0a5b8f3

Please sign in to comment.