@@ -3,6 +3,7 @@ import React from 'react';
33import type { Node } from 'react' ;
44import { Platform , View } from 'react-native' ;
55import type { ViewStyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet' ;
6+ import { useSafeAreaInsets } from 'react-native-safe-area-context' ;
67
78import KeyboardAvoidingView from '../third/react-native/KeyboardAvoidingView' ;
89
@@ -12,8 +13,9 @@ type Props = $ReadOnly<{|
1213 style ? : ViewStyleProp ,
1314 contentContainerStyle ? : ViewStyleProp ,
1415
15- /** How much the top of `KeyboardAvoider`'s layout *parent* is
16- * displaced downward from the top of the screen.
16+ /**
17+ * How much the top of `KeyboardAvoider`'s layout *parent* is
18+ * displaced downward from the top of the screen.
1719 *
1820 * If this isn't set correctly, the keyboard will hide some of
1921 * the bottom of the screen (an area whose height is what this
@@ -30,6 +32,19 @@ type Props = $ReadOnly<{|
3032 * we can use to balance the equation if we need to.
3133 */
3234 keyboardVerticalOffset ? : number ,
35+
36+ /**
37+ * Whether to shorten the excursion by the height of the bottom inset.
38+ *
39+ * Use this when a child component uses SafeAreaView to pad the bottom
40+ * inset, and you want the open keyboard to cover that padding.
41+ *
42+ * (SafeAreaView has a bug where it applies a constant padding no matter
43+ * where it's positioned onscreen -- so in particular, if you ask for
44+ * bottom padding, you'll get bottom padding even when KeyboardAvoider
45+ * pushes the SafeAreaView up and out of the bottom inset.)
46+ */
47+ compensateOverpadding ? : boolean ,
3348| } > ;
3449
3550/**
@@ -40,7 +55,16 @@ type Props = $ReadOnly<{|
4055 * to that component.
4156 */
4257export default function KeyboardAvoider ( props : Props ) : Node {
43- const { behavior, children, style, contentContainerStyle, keyboardVerticalOffset } = props ;
58+ const {
59+ behavior,
60+ children,
61+ style,
62+ contentContainerStyle,
63+ keyboardVerticalOffset = 0 , // Same default value as KeyboardAvoidingView
64+ compensateOverpadding = false ,
65+ } = props ;
66+
67+ const bottomInsetHeight = useSafeAreaInsets ( ) . bottom ;
4468
4569 if ( Platform . OS === 'android' ) {
4670 return < View style = { style } > { children } </ View > ;
@@ -51,7 +75,13 @@ export default function KeyboardAvoider(props: Props): Node {
5175 behavior = { behavior }
5276 contentContainerStyle = { contentContainerStyle }
5377 // See comment on this prop in the jsdoc.
54- keyboardVerticalOffset = { keyboardVerticalOffset }
78+ keyboardVerticalOffset = {
79+ keyboardVerticalOffset
80+ // A negative term here reduces the bottom inset we use for the
81+ // child, when the keyboard is open, so that the keyboard covers its
82+ // bottom padding.
83+ + ( compensateOverpadding ? - bottomInsetHeight : 0 )
84+ }
5585 style = { style }
5686 >
5787 { children }
0 commit comments