diff --git a/packages/bottom-tabs/src/views/BottomTabBar.js b/packages/bottom-tabs/src/views/BottomTabBar.js index 2a00d049..2179ce7f 100644 --- a/packages/bottom-tabs/src/views/BottomTabBar.js +++ b/packages/bottom-tabs/src/views/BottomTabBar.js @@ -2,18 +2,20 @@ import React from 'react'; import { + Animated, TouchableWithoutFeedback, StyleSheet, View, + Keyboard, Platform, } from 'react-native'; import { SafeAreaView } from '@react-navigation/native'; -import Animated from 'react-native-reanimated'; import CrossFadeIcon from './CrossFadeIcon'; import withDimensions from '../utils/withDimensions'; export type TabBarOptions = { + keyboardHidesTabBar: boolean, activeTintColor?: string, inactiveTintColor?: string, activeBackgroundColor?: string, @@ -45,6 +47,12 @@ type Props = TabBarOptions & { safeAreaInset: { top: string, right: string, bottom: string, left: string }, }; +type State = { + layout: { height: number, width: number }, + keyboard: boolean, + visible: Animated.Value, +}; + const majorVersion = parseInt(Platform.Version, 10); const isIos = Platform.OS === 'ios'; const isIOS11 = majorVersion >= 11 && isIos; @@ -79,8 +87,9 @@ class TouchableWithoutFeedbackWrapper extends React.Component<*> { } } -class TabBarBottom extends React.Component { +class TabBarBottom extends React.Component { static defaultProps = { + keyboardHidesTabBar: true, activeTintColor: '#007AFF', activeBackgroundColor: 'transparent', inactiveTintColor: '#8E8E93', @@ -92,6 +101,66 @@ class TabBarBottom extends React.Component { safeAreaInset: { bottom: 'always', top: 'never' }, }; + state = { + layout: { height: 0, width: 0 }, + keyboard: false, + visible: new Animated.Value(1), + }; + + componentDidMount() { + if (Platform.OS === 'ios') { + Keyboard.addListener('keyboardWillShow', this._handleKeyboardShow); + Keyboard.addListener('keyboardWillHide', this._handleKeyboardHide); + } else { + Keyboard.addListener('keyboardDidShow', this._handleKeyboardShow); + Keyboard.addListener('keyboardDidHide', this._handleKeyboardHide); + } + } + + componentWillUnmount() { + if (Platform.OS === 'ios') { + Keyboard.removeListener('keyboardWillShow', this._handleKeyboardShow); + Keyboard.removeListener('keyboardWillHide', this._handleKeyboardHide); + } else { + Keyboard.removeListener('keyboardDidShow', this._handleKeyboardShow); + Keyboard.removeListener('keyboardDidHide', this._handleKeyboardHide); + } + } + + _handleKeyboardShow = () => + this.setState({ keyboard: true }, () => + Animated.timing(this.state.visible, { + toValue: 0, + duration: 150, + useNativeDriver: true, + }).start() + ); + + _handleKeyboardHide = () => + Animated.timing(this.state.visible, { + toValue: 1, + duration: 100, + useNativeDriver: true, + }).start(() => { + this.setState({ keyboard: false }); + }); + + _handleLayout = e => { + const { layout } = this.state; + const { height, width } = e.nativeEvent.layout; + + if (height === layout.height && width === layout.width) { + return; + } + + this.setState({ + layout: { + height, + width, + }, + }); + }; + _renderLabel = ({ route, focused }) => { const { activeTintColor, @@ -202,6 +271,7 @@ class TabBarBottom extends React.Component { render() { const { navigation, + keyboardHidesTabBar, activeBackgroundColor, inactiveBackgroundColor, onTabPress, @@ -222,62 +292,71 @@ class TabBarBottom extends React.Component { ]; return ( - - {routes.map((route, index) => { - const focused = index === navigation.state.index; - const scene = { route, focused }; - - const accessibilityLabel = this.props.getAccessibilityLabel({ - route, - }); - - const accessibilityRole = - this.props.getAccessibilityRole({ + + ); } } @@ -292,6 +371,12 @@ const styles = StyleSheet.create({ borderTopColor: 'rgba(0, 0, 0, .3)', flexDirection: 'row', }, + container: { + left: 0, + right: 0, + bottom: 0, + elevation: 8, + }, tabBarCompact: { height: COMPACT_HEIGHT, },