diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index c7dde5740df2..134c4b4f0d40 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -221,7 +221,12 @@ function BaseModal( shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaMargin, // enableEdgeToEdgeBottomSafeAreaPadding is used as a temporary solution to disable safe area bottom spacing on modals, to allow edge-to-edge content - shouldAddBottomSafeAreaPadding: !enableEdgeToEdgeBottomSafeAreaPadding && (!avoidKeyboard || !keyboardStateContextValue?.isKeyboardShown) && shouldAddBottomSafeAreaPadding, + shouldAddBottomSafeAreaPadding: + (!avoidKeyboard || + (!keyboardStateContextValue?.isKeyboardShown && !keyboardStateContextValue.isKeyboardWillShow) || + (keyboardStateContextValue.isKeyboardShown && keyboardStateContextValue.isKeyboardWillHide)) && + shouldAddBottomSafeAreaPadding && + !enableEdgeToEdgeBottomSafeAreaPadding, shouldAddTopSafeAreaPadding, modalContainerStyleMarginTop: modalContainerStyle.marginTop, modalContainerStyleMarginBottom: modalContainerStyle.marginBottom, diff --git a/src/components/withKeyboardState.tsx b/src/components/withKeyboardState.tsx index 15150485d499..cc3f58bb8bf5 100755 --- a/src/components/withKeyboardState.tsx +++ b/src/components/withKeyboardState.tsx @@ -14,18 +14,53 @@ type KeyboardStateContextValue = { keyboardHeight: number; isKeyboardAnimatingRef: MutableRefObject; + + /** Whether the keyboard is about to show */ + isKeyboardWillShow: boolean; + + /** Whether the keyboard is about to hide */ + isKeyboardWillHide: boolean; }; const KeyboardStateContext = createContext({ isKeyboardShown: false, keyboardHeight: 0, isKeyboardAnimatingRef: {current: false}, + isKeyboardWillShow: false, + isKeyboardWillHide: false, }); function KeyboardStateProvider({children}: ChildrenProps): ReactElement | null { const {bottom} = useSafeAreaInsets(); const [keyboardHeight, setKeyboardHeight] = useState(0); const isKeyboardAnimatingRef = useRef(false); + const [isKeyboardWillShow, setIsKeyboardWillShow] = useState(false); + const [isKeyboardWillHide, setIsKeyboardWillHide] = useState(false); + useEffect(() => { + const keyboardDidShowListener = KeyboardEvents.addListener('keyboardDidShow', (e) => { + setKeyboardHeight(getKeyboardHeight(e.height, bottom)); + setIsKeyboardWillShow(false); + }); + const keyboardDidHideListener = KeyboardEvents.addListener('keyboardDidHide', () => { + setKeyboardHeight(0); + setIsKeyboardWillHide(false); + }); + const keyboardWillShowListener = KeyboardEvents.addListener('keyboardWillShow', () => { + setIsKeyboardWillShow(true); + setIsKeyboardWillHide(false); + }); + const keyboardWillHideListener = KeyboardEvents.addListener('keyboardWillHide', () => { + setIsKeyboardWillHide(true); + setIsKeyboardWillShow(false); + }); + + return () => { + keyboardDidShowListener.remove(); + keyboardDidHideListener.remove(); + keyboardWillShowListener.remove(); + keyboardWillHideListener.remove(); + }; + }, [bottom]); useEffect(() => { const keyboardDidShowListener = KeyboardEvents.addListener('keyboardDidShow', (e) => { @@ -66,8 +101,10 @@ function KeyboardStateProvider({children}: ChildrenProps): ReactElement | null { keyboardHeight, isKeyboardShown: keyboardHeight !== 0, isKeyboardAnimatingRef, + isKeyboardWillHide, + isKeyboardWillShow, }), - [keyboardHeight], + [keyboardHeight, isKeyboardWillHide, isKeyboardWillShow], ); return {children}; }