diff --git a/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap b/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap
index 453a12fb..33e23bd7 100644
--- a/src/navigators/__tests__/__snapshots__/TabNavigator-test.js.snap
+++ b/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/src/views/TabView/TabBarBottom.js b/src/views/TabView/TabBarBottom.js
index b218d3c3..c261e60c 100644
--- a/src/views/TabView/TabBarBottom.js
+++ b/src/views/TabView/TabBarBottom.js
@@ -8,10 +8,12 @@ import {
View,
Platform,
Keyboard,
+ Dimensions,
} from 'react-native';
import TabBarIcon from './TabBarIcon';
import SafeAreaView from '../SafeAreaView';
import withOrientation from '../withOrientation';
+import type { Layout } from 'react-native-tab-view/src/TabViewTypeDefinitions';
import type {
NavigationRoute,
@@ -51,11 +53,16 @@ type Props = {
tabStyle?: ViewStyleProp,
showIcon?: boolean,
isLandscape: boolean,
+ layout: Layout,
+ adaptive: boolean,
};
const majorVersion = parseInt(Platform.Version, 10);
const isIos = Platform.OS === 'ios';
-const useHorizontalTabs = majorVersion >= 11 && isIos;
+const isIOS11 = majorVersion >= 11 && isIos;
+const isTablet =
+ Dimensions.get('window').height / Dimensions.get('window').width < 1.6;
+const defaultMaxTabBarItemWidth = 125;
class TabBarBottom extends React.PureComponent {
// See https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/UIKitUICatalog/UITabBar.html
@@ -67,6 +74,7 @@ class TabBarBottom extends React.PureComponent {
showLabel: true,
showIcon: true,
allowFontScaling: true,
+ adaptive: isIOS11,
};
_renderLabel = (scene: TabScene) => {
@@ -99,19 +107,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}
@@ -147,7 +154,7 @@ class TabBarBottom extends React.PureComponent {
inactiveTintColor={inactiveTintColor}
renderIcon={renderIcon}
scene={scene}
- style={showLabel && useHorizontalTabs ? {} : styles.icon}
+ style={showLabel && this._shouldUseHorizontalTabs() ? {} : styles.icon}
/>
);
};
@@ -158,6 +165,65 @@ 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 isTablet;
+ }
+
+ const isHeightConstrained = layout.height < 500;
+ if (isHeightConstrained) {
+ return isLandscape;
+ } else {
+ const maxTabBarItemWidth = this._tabItemMaxWidth();
+ return routes.length * maxTabBarItemWidth <= tabBarWidth;
+ }
+ }
+
render() {
const {
position,
@@ -171,17 +237,20 @@ class TabBarBottom extends React.PureComponent {
animateStyle,
tabStyle,
isLandscape,
+ layout,
} = this.props;
const { routes } = navigation.state;
const previousScene = routes[navigation.state.index];
// Prepend '-1', so there are always at least 2 items in inputRange
const inputRange = [-1, ...routes.map((x: *, i: number) => i)];
+ const isHeightConstrained =
+ layout.height === 0 ? !isTablet : layout.height < 500;
const tabBarStyle = [
styles.tabBar,
- isLandscape && useHorizontalTabs
- ? styles.tabBarLandscape
- : styles.tabBarPortrait,
+ this._shouldUseHorizontalTabs() && isHeightConstrained
+ ? styles.tabBarCompact
+ : styles.tabBarRegular,
style,
];
@@ -220,17 +289,19 @@ class TabBarBottom extends React.PureComponent {
? onPress({ previousScene, scene, jumpToIndex })
: jumpToIndex(index)}
>
-
- {this._renderIcon(scene)}
- {this._renderLabel(scene)}
+
+
+ {this._renderIcon(scene)}
+ {this._renderLabel(scene)}
+
);
@@ -241,8 +312,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
@@ -250,16 +319,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',
@@ -274,9 +342,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/src/views/__tests__/__snapshots__/TabView-test.js.snap b/src/views/__tests__/__snapshots__/TabView-test.js.snap
index 7f3877c3..9d4c1b7f 100644
--- a/src/views/__tests__/__snapshots__/TabView-test.js.snap
+++ b/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
-