diff --git a/packages/tabs/package.json b/packages/tabs/package.json index 32208c5a..b5c85d66 100644 --- a/packages/tabs/package.json +++ b/packages/tabs/package.json @@ -42,7 +42,7 @@ "dependencies": { "hoist-non-react-statics": "^3.3.2", "react-lifecycles-compat": "^3.0.4", - "react-native-safe-area-view": "^0.14.9", + "react-native-iphone-x-helper": "^1.3.0", "react-native-tab-view": "^2.15.2" }, "devDependencies": { diff --git a/packages/tabs/src/types.tsx b/packages/tabs/src/types.tsx index 50e1e163..7e934373 100644 --- a/packages/tabs/src/types.tsx +++ b/packages/tabs/src/types.tsx @@ -6,7 +6,6 @@ import { TextStyle, ViewStyle, } from 'react-native'; -import SafeAreaView from 'react-native-safe-area-view'; import Animated from 'react-native-reanimated'; import { NavigationRoute, @@ -94,7 +93,12 @@ export type BottomTabBarOptions = { | LabelPosition | ((options: { deviceOrientation: Orientation }) => LabelPosition); adaptive?: boolean; - safeAreaInset?: React.ComponentProps['forceInset']; + safeAreaInset?: { + top?: 'always' | 'never' | number; + right?: 'always' | 'never' | number; + bottom?: 'always' | 'never' | number; + left?: 'always' | 'never' | number; + }; style?: StyleProp; }; diff --git a/packages/tabs/src/views/BottomTabBar.tsx b/packages/tabs/src/views/BottomTabBar.tsx index 0915efce..7d351fd0 100644 --- a/packages/tabs/src/views/BottomTabBar.tsx +++ b/packages/tabs/src/views/BottomTabBar.tsx @@ -8,7 +8,10 @@ import { Platform, LayoutChangeEvent, } from 'react-native'; -import SafeAreaView from 'react-native-safe-area-view'; +import { + getStatusBarHeight, + getBottomSpace, +} from 'react-native-iphone-x-helper'; import { ThemeColors, ThemeContext, NavigationRoute } from 'react-navigation'; import CrossFadeIcon from './CrossFadeIcon'; @@ -30,6 +33,9 @@ const majorVersion = parseInt(Platform.Version as string, 10); const isIos = Platform.OS === 'ios'; const isIOS11 = majorVersion >= 11 && isIos; +const DEFAULT_HEIGHT = 49; +const COMPACT_HEIGHT = 29; + const DEFAULT_MAX_TAB_ITEM_WIDTH = 125; const DEFAULT_KEYBOARD_ANIMATION_CONFIG: KeyboardHidesTabBarAnimationConfig = { show: { @@ -103,9 +109,7 @@ class TabBarBottom extends React.Component { showIcon: true, allowFontScaling: true, adaptive: isIOS11, - safeAreaInset: { bottom: 'always', top: 'never' } as React.ComponentProps< - typeof SafeAreaView - >['forceInset'], + safeAreaInset: { bottom: 'always', top: 'never' } as const, }; // eslint-disable-next-line react/sort-comp @@ -394,6 +398,7 @@ class TabBarBottom extends React.Component { keyboardHidesTabBar, onTabPress, onTabLongPress, + isLandscape, safeAreaInset, style, tabStyle, @@ -436,13 +441,42 @@ class TabBarBottom extends React.Component { marginVertical, }; + const statusBarHeight = getStatusBarHeight(true); + const horizontalInset = isLandscape ? statusBarHeight : 0; + const insets = { + bottom: + typeof safeAreaInset?.bottom === 'number' + ? safeAreaInset.bottom + : safeAreaInset?.bottom === 'never' + ? 0 + : getBottomSpace(), + left: + typeof safeAreaInset?.left === 'number' + ? safeAreaInset.left + : safeAreaInset?.left === 'never' + ? 0 + : horizontalInset, + right: + typeof safeAreaInset?.right === 'number' + ? safeAreaInset.right + : safeAreaInset?.right === 'never' + ? 0 + : horizontalInset, + }; + const tabBarStyle = [ + { + height: + // @ts-ignore: isPad exists in runtime but not available in type defs + (this._shouldUseHorizontalLabels() && !Platform.isPad + ? COMPACT_HEIGHT + : DEFAULT_HEIGHT) + insets.bottom, + paddingBottom: insets.bottom, + paddingLeft: insets.left, + paddingRight: insets.right, + }, styles.tabBar, isDark ? styles.tabBarDark : styles.tabBarLight, - // @ts-ignore - this._shouldUseHorizontalLabels() && !Platform.isPad - ? styles.tabBarCompact - : styles.tabBarRegular, innerStyle, ]; @@ -473,7 +507,7 @@ class TabBarBottom extends React.Component { } onLayout={this._handleLayout} > - + {routes.map((route, index) => { const focused = index === navigation.state.index; const scene = { route, focused }; @@ -524,15 +558,12 @@ class TabBarBottom extends React.Component { ); })} - + ); } } -const DEFAULT_HEIGHT = 49; -const COMPACT_HEIGHT = 29; - const styles = StyleSheet.create({ tabBar: { borderTopWidth: StyleSheet.hairlineWidth, @@ -549,12 +580,6 @@ const styles = StyleSheet.create({ container: { elevation: 8, }, - tabBarCompact: { - height: COMPACT_HEIGHT, - }, - tabBarRegular: { - height: DEFAULT_HEIGHT, - }, tab: { flex: 1, alignItems: isIos ? 'center' : 'stretch',