UNPKG

@wordpress/components

Version:
107 lines (105 loc) 3.81 kB
/** * External dependencies */ import { KeyboardAvoidingView as IOSKeyboardAvoidingView, Animated, Keyboard, Dimensions, View } from 'react-native'; import SafeArea from 'react-native-safe-area'; /** * WordPress dependencies */ import { useEffect, useRef, useState } from '@wordpress/element'; import { useResizeObserver } from '@wordpress/compose'; /** * Internal dependencies */ import useIsFloatingKeyboard from '../utils/use-is-floating-keyboard'; import styles from './styles.scss'; import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; const AnimatedKeyboardAvoidingView = Animated.createAnimatedComponent(IOSKeyboardAvoidingView); const MIN_HEIGHT = 44; export const KeyboardAvoidingView = ({ parentHeight, style, withAnimatedHeight = false, ...otherProps }) => { const [resizeObserver, sizes] = useResizeObserver(); const [isKeyboardOpen, setIsKeyboardOpen] = useState(false); const [safeAreaBottomInset, setSafeAreaBottomInset] = useState(0); const { height = 0 } = sizes || {}; const floatingKeyboard = useIsFloatingKeyboard(); const animatedHeight = useRef(new Animated.Value(MIN_HEIGHT)).current; const { height: fullHeight } = Dimensions.get('screen'); const keyboardVerticalOffset = fullHeight - parentHeight; useEffect(() => { SafeArea.getSafeAreaInsetsForRootView().then(({ safeAreaInsets }) => { setSafeAreaBottomInset(safeAreaInsets.bottom); }); const safeAreaSubscription = SafeArea.addEventListener('safeAreaInsetsForRootViewDidChange', onSafeAreaInsetsUpdate); const keyboardShowSubscription = Keyboard.addListener('keyboardWillShow', onKeyboardWillShow); const keyboardHideSubscription = Keyboard.addListener('keyboardWillHide', onKeyboardWillHide); return () => { safeAreaSubscription.remove(); keyboardShowSubscription.remove(); keyboardHideSubscription.remove(); }; // See https://github.com/WordPress/gutenberg/pull/41166 }, []); function onSafeAreaInsetsUpdate({ safeAreaInsets }) { setSafeAreaBottomInset(safeAreaInsets.bottom); } function onKeyboardWillShow({ endCoordinates }) { setIsKeyboardOpen(true); animatedHeight.setValue(endCoordinates.height + MIN_HEIGHT); } function onKeyboardWillHide({ duration, startCoordinates }) { // The startCoordinates.height is set to wrong value when we use cmd + k for hide the keyboard (Have no idea why). // Because of that the `setIsKeyboardOpened` is not invoked and the state of keyboard is wrong. // The keyboardIsOpenBreakpoint use 100 as a fallback if the startCoordinates.height is too small (cmd + k case) const keyboardIsOpenBreakpoint = startCoordinates.height > 100 ? startCoordinates.height / 3 : 100; const animatedListenerId = animatedHeight.addListener(({ value }) => { if (value < keyboardIsOpenBreakpoint) { setIsKeyboardOpen(false); } }); Animated.timing(animatedHeight, { toValue: MIN_HEIGHT, duration, useNativeDriver: false }).start(() => { animatedHeight.removeListener(animatedListenerId); }); } return /*#__PURE__*/_jsx(AnimatedKeyboardAvoidingView, { ...otherProps, enabled: !floatingKeyboard, behavior: "padding", keyboardVerticalOffset: keyboardVerticalOffset, style: withAnimatedHeight ? [style, { height: animatedHeight, marginBottom: isKeyboardOpen ? -safeAreaBottomInset : 0 }] : style, children: /*#__PURE__*/_jsxs(View, { style: [{ top: -height + MIN_HEIGHT }, styles.animatedChildStyle, !withAnimatedHeight && styles.defaultChildStyle], children: [resizeObserver, otherProps.children] }) }); }; export default KeyboardAvoidingView; //# sourceMappingURL=index.ios.js.map