Skip to content

Commit

Permalink
Add onTabPress callback to screen's navigationOptions.tabBar (rea…
Browse files Browse the repository at this point in the history
…ct-navigation#486)

Pressing a tab bar often requires some kind of side effects other than
navigation to be performed. This PR will allow a screen accept
`onTabPress` callback as an option. It will be invoked exactly once on
every press on the screen's corresponding tab button, receiving a
`TabScene` object as an argument.
  • Loading branch information
kimdhoe committed Mar 12, 2017
1 parent 00972a3 commit f120c72
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/views/TabView/TabBarBottom.js
Expand Up @@ -36,6 +36,7 @@ type Props = {
navigationState: NavigationState;
jumpToIndex: (index: number) => void;
getLabel: (scene: TabScene) => ?(React.Element<*> | string);
getTabPressCallback: (scene: TabScene) => Function;
renderIcon: (scene: TabScene) => React.Element<*>;
showLabel: boolean;
style?: Style;
Expand All @@ -57,6 +58,13 @@ export default class TabBarBottom extends PureComponent<DefaultProps, Props, voi

props: Props;

_onTabPress = (scene: TabScene) => {
const { getTabPressCallback, jumpToIndex } = this.props
const onTabPress = getTabPressCallback(scene);
onTabPress(scene);
jumpToIndex(scene.index);
};

_renderLabel = (scene: TabScene) => {
const {
position,
Expand Down Expand Up @@ -147,7 +155,7 @@ export default class TabBarBottom extends PureComponent<DefaultProps, Props, voi
});
const justifyContent = this.props.showIcon ? 'flex-end' : 'center';
return (
<TouchableWithoutFeedback key={route.key} onPress={() => jumpToIndex(index)}>
<TouchableWithoutFeedback key={route.key} onPress={() => this._onTabPress(scene)}>
<Animated.View style={[styles.tab, { backgroundColor, justifyContent }]}>
{this._renderIcon(scene)}
{this._renderLabel(scene)}
Expand Down
19 changes: 19 additions & 0 deletions src/views/TabView/TabBarTop.js
Expand Up @@ -35,6 +35,7 @@ type Props = {
position: Animated.Value;
navigationState: NavigationState;
getLabel: (scene: TabScene) => ?(React.Element<*> | string);
getTabPressCallback: (scene: TabScene) => Function;
renderIcon: (scene: TabScene) => React.Element<*>;
labelStyle?: Style;
};
Expand All @@ -51,6 +52,23 @@ export default class TabBarTop extends PureComponent<DefaultProps, Props, void>

props: Props;

_onTabPress = (route: NavigationRoute) => {
const { navigationState, getTabPressCallback } = this.props;
const { routes } = navigationState;
const routesLength = routes.length;
let index = -1;
for (let i = 0; i < routesLength; i++) {
if (routes[i] === route) {
index = i;
break;
}
}
const focused = index === navigationState.index;
const scene = { route, index, focused };
const onTabPress = getTabPressCallback(scene);
onTabPress(scene);
}

_renderLabel = (scene: TabScene) => {
const {
position,
Expand Down Expand Up @@ -123,6 +141,7 @@ export default class TabBarTop extends PureComponent<DefaultProps, Props, void>
return (
<TabBar
{...props}
onTabPress={this._onTabPress}
renderIcon={this._renderIcon}
renderLabel={this._renderLabel}
/>
Expand Down
12 changes: 12 additions & 0 deletions src/views/TabView/TabView.js
Expand Up @@ -107,6 +107,17 @@ class TabView extends PureComponent<void, Props, void> {
return route.routeName;
};

_getTabPressCallback = ({ route }: TabScene): Function => {
const tabBar = this.props.router.getScreenConfig(
this.props.childNavigationProps[route.key],
'tabBar'
);
if (tabBar && typeof tabBar.onTabPress === 'function') {
return tabBar.onTabPress;
}
return () => {};
};

_renderIcon = ({ focused, route, tintColor }: TabScene) => {
const tabBar = this.props.router.getScreenConfig(
this.props.childNavigationProps[route.key],
Expand Down Expand Up @@ -135,6 +146,7 @@ class TabView extends PureComponent<void, Props, void> {
{...tabBarOptions}
navigation={this.props.navigation}
getLabel={this._getLabel}
getTabPressCallback={this._getTabPressCallback}
renderIcon={this._renderIcon}
animationEnabled={animationEnabled}
/>
Expand Down

0 comments on commit f120c72

Please sign in to comment.