diff --git a/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap b/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap
index 453a12fb..33e23bd7 100644
--- a/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap
+++ b/packages/react-navigation/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap
@@ -105,68 +105,81 @@ exports[`TabNavigator renders successfully 1`] = `
"alignItems": "center",
"backgroundColor": "rgba(0, 0, 0, 0)",
"flex": 1,
- "justifyContent": "flex-end",
}
}
testID={undefined}
>
-
+
+
+
+
+ >
+ Welcome anonymous
+
-
- Welcome anonymous
-
diff --git a/packages/react-navigation/src/views/TabView/TabBarBottom.js b/packages/react-navigation/src/views/TabView/TabBarBottom.js
index 133069fa..e4f71f1b 100644
--- a/packages/react-navigation/src/views/TabView/TabBarBottom.js
+++ b/packages/react-navigation/src/views/TabView/TabBarBottom.js
@@ -13,7 +13,8 @@ import withOrientation from '../withOrientation';
const majorVersion = parseInt(Platform.Version, 10);
const isIos = Platform.OS === 'ios';
-const useHorizontalTabs = majorVersion >= 11 && isIos;
+const isIOS11 = majorVersion >= 11 && isIos;
+const defaultMaxTabBarItemWidth = 125;
class TabBarBottom extends React.PureComponent {
// See https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/UIKitUICatalog/UITabBar.html
@@ -25,6 +26,7 @@ class TabBarBottom extends React.PureComponent {
showLabel: true,
showIcon: true,
allowFontScaling: true,
+ adaptive: isIOS11,
};
_renderLabel = scene => {
@@ -56,19 +58,18 @@ class TabBarBottom extends React.PureComponent {
const tintColor = scene.focused ? activeTintColor : inactiveTintColor;
const label = this.props.getLabel({ ...scene, tintColor });
- let marginLeft = 0;
- if (isLandscape && showIcon && useHorizontalTabs) {
- marginLeft = LABEL_LEFT_MARGIN;
- }
- let marginTop = 0;
- if (!isLandscape && showIcon && useHorizontalTabs) {
- marginTop = LABEL_TOP_MARGIN;
- }
if (typeof label === 'string') {
return (
{label}
@@ -104,7 +105,7 @@ class TabBarBottom extends React.PureComponent {
inactiveTintColor={inactiveTintColor}
renderIcon={renderIcon}
scene={scene}
- style={showLabel && useHorizontalTabs ? {} : styles.icon}
+ style={showLabel && this._shouldUseHorizontalTabs() ? {} : styles.icon}
/>
);
};
@@ -115,6 +116,64 @@ class TabBarBottom extends React.PureComponent {
return testIDProps;
};
+ _tabItemMaxWidth() {
+ const { tabStyle, layout } = this.props;
+ let maxTabBarItemWidth;
+
+ const flattenedTabStyle = StyleSheet.flatten(tabStyle);
+
+ if (flattenedTabStyle) {
+ if (typeof flattenedTabStyle.width === 'number') {
+ maxTabBarItemWidth = flattenedTabStyle.width;
+ } else if (
+ typeof flattenedTabStyle.width === 'string' &&
+ flattenedTabStyle.endsWith('%')
+ ) {
+ const width = parseFloat(flattenedTabStyle.width);
+ if (Number.isFinite(width)) {
+ maxTabBarItemWidth = layout.width * (width / 100);
+ }
+ } else if (typeof flattenedTabStyle.maxWidth === 'number') {
+ maxTabBarItemWidth = flattenedTabStyle.maxWidth;
+ } else if (
+ typeof flattenedTabStyle.maxWidth === 'string' &&
+ flattenedTabStyle.endsWith('%')
+ ) {
+ const width = parseFloat(flattenedTabStyle.maxWidth);
+ if (Number.isFinite(width)) {
+ maxTabBarItemWidth = layout.width * (width / 100);
+ }
+ }
+ }
+
+ if (!maxTabBarItemWidth) {
+ maxTabBarItemWidth = defaultMaxTabBarItemWidth;
+ }
+
+ return maxTabBarItemWidth;
+ }
+
+ _shouldUseHorizontalTabs() {
+ const { routes } = this.props.navigation.state;
+ const { isLandscape, layout, adaptive, tabStyle } = this.props;
+
+ if (!adaptive) {
+ return false;
+ }
+
+ let tabBarWidth = layout.width;
+ if (tabBarWidth === 0) {
+ return Platform.isPad;
+ }
+
+ if (!Platform.isPad) {
+ return isLandscape;
+ } else {
+ const maxTabBarItemWidth = this._tabItemMaxWidth();
+ return routes.length * maxTabBarItemWidth <= tabBarWidth;
+ }
+ }
+
render() {
const {
position,
@@ -136,9 +195,9 @@ class TabBarBottom extends React.PureComponent {
const tabBarStyle = [
styles.tabBar,
- isLandscape && useHorizontalTabs
- ? styles.tabBarLandscape
- : styles.tabBarPortrait,
+ this._shouldUseHorizontalTabs() && !Platform.isPad
+ ? styles.tabBarCompact
+ : styles.tabBarRegular,
style,
];
@@ -178,17 +237,19 @@ class TabBarBottom extends React.PureComponent {
: jumpToIndex(index)
}
>
-
- {this._renderIcon(scene)}
- {this._renderLabel(scene)}
+
+
+ {this._renderIcon(scene)}
+ {this._renderLabel(scene)}
+
);
@@ -199,8 +260,6 @@ class TabBarBottom extends React.PureComponent {
}
}
-const LABEL_LEFT_MARGIN = 20;
-const LABEL_TOP_MARGIN = 15;
const styles = StyleSheet.create({
tabBar: {
backgroundColor: '#F7F7F7', // Default background color in iOS 10
@@ -208,16 +267,15 @@ const styles = StyleSheet.create({
borderTopColor: 'rgba(0, 0, 0, .3)',
flexDirection: 'row',
},
- tabBarLandscape: {
+ tabBarCompact: {
height: 29,
},
- tabBarPortrait: {
+ tabBarRegular: {
height: 49,
},
tab: {
flex: 1,
alignItems: isIos ? 'center' : 'stretch',
- justifyContent: 'flex-end',
},
tabPortrait: {
justifyContent: 'flex-end',
@@ -232,9 +290,15 @@ const styles = StyleSheet.create({
},
label: {
textAlign: 'center',
+ backgroundColor: 'transparent',
+ },
+ labelBeneath: {
fontSize: 10,
marginBottom: 1.5,
- backgroundColor: 'transparent',
+ },
+ labelBeside: {
+ fontSize: 13,
+ marginLeft: 20,
},
});
diff --git a/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap b/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap
index 3f75ccaa..904069ec 100644
--- a/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap
+++ b/packages/react-navigation/src/views/__tests__/__snapshots__/TabView-test.js.snap
@@ -61,68 +61,81 @@ exports[`TabBarBottom renders successfully 1`] = `
"alignItems": "center",
"backgroundColor": "rgba(0, 0, 0, 0)",
"flex": 1,
- "justifyContent": "flex-end",
}
}
testID={undefined}
>
-
+
+
+
+
+ >
+ s1
+
-
- s1
-