diff --git a/packages/block-editor/src/components/page-template-picker/picker.native.js b/packages/block-editor/src/components/page-template-picker/picker.native.js index e419e0bf8d019d..25bb4b772ec242 100644 --- a/packages/block-editor/src/components/page-template-picker/picker.native.js +++ b/packages/block-editor/src/components/page-template-picker/picker.native.js @@ -8,7 +8,7 @@ import { useDispatch, useSelect } from '@wordpress/data'; * External dependencies */ import { logUserEvent, userEvents } from 'react-native-gutenberg-bridge'; -import { Animated } from 'react-native'; +import { Animated, Dimensions, Keyboard } from 'react-native'; /** * Internal dependencies @@ -18,6 +18,9 @@ import Container from './container'; import getDefaultTemplates from './default-templates'; import Preview from './preview'; +// Used to hide the picker if there's no enough space in the window +const PICKER_HEIGHT_OFFSET = 150; + const __experimentalPageTemplatePicker = ( { templates = getDefaultTemplates(), visible, @@ -33,12 +36,43 @@ const __experimentalPageTemplatePicker = ( { const [ templatePreview, setTemplatePreview ] = useState(); const [ pickerVisible, setPickerVisible ] = useState( visible ); - const contentOpacity = useRef( new Animated.Value( 0 ) ); + const contentOpacity = useRef( new Animated.Value( 0 ) ).current; useEffect( () => { - onPickerAnimation(); + if ( shouldShowPicker() && visible && ! pickerVisible ) { + setPickerVisible( true ); + } + startPickerAnimation( visible ); + + Keyboard.addListener( 'keyboardDidShow', onKeyboardDidShow ); + Keyboard.addListener( 'keyboardDidHide', onKeyboardDidHide ); + + return () => { + Keyboard.removeListener( 'keyboardDidShow', onKeyboardDidShow ); + Keyboard.removeListener( 'keyboardDidHide', onKeyboardDidHide ); + }; }, [ visible ] ); + const onKeyboardDidShow = () => { + if ( visible ) { + startPickerAnimation( shouldShowPicker() ); + } + }; + + const onKeyboardDidHide = () => { + if ( visible ) { + setPickerVisible( true ); + startPickerAnimation( true ); + } + }; + + const shouldShowPicker = () => { + // On smaller devices on landscape we hide the picker + // so it doesn't overlap with the editor's content + const windowHeight = Dimensions.get( 'window' ).height; + return PICKER_HEIGHT_OFFSET < windowHeight / 3; + }; + const onApply = () => { editPost( { title: title || templatePreview.name, @@ -50,18 +84,14 @@ const __experimentalPageTemplatePicker = ( { setTemplatePreview( undefined ); }; - const onPickerAnimation = () => { - if ( visible && ! pickerVisible ) { - setPickerVisible( true ); - } - - Animated.timing( contentOpacity.current, { - toValue: visible ? 1 : 0, + const startPickerAnimation = ( isVisible ) => { + Animated.timing( contentOpacity, { + toValue: isVisible ? 1 : 0, duration: 300, useNativeDriver: true, } ).start( () => { - if ( ! visible ) { - setPickerVisible( false ); + if ( ! isVisible ) { + setPickerVisible( isVisible ); } } ); }; @@ -71,7 +101,7 @@ const __experimentalPageTemplatePicker = ( { } return ( - + { templates.map( ( template ) => (