diff --git a/example/src/screens/advanced/KeyboardHandlingExample.tsx b/example/src/screens/advanced/KeyboardHandlingExample.tsx index e490b547d..3681c72d7 100644 --- a/example/src/screens/advanced/KeyboardHandlingExample.tsx +++ b/example/src/screens/advanced/KeyboardHandlingExample.tsx @@ -18,7 +18,7 @@ const KeyboardHandlingExample = () => { const bottomSheetRef = useRef(null); // variables - const snapPoints = useMemo(() => [SEARCH_HANDLE_HEIGHT + 34, 500], []); + const snapPoints = useMemo(() => [SEARCH_HANDLE_HEIGHT + 34, 450], []); // callbacks const handleToggleKeyboardBehavior = useCallback(() => { diff --git a/src/components/bottomSheet/BottomSheet.tsx b/src/components/bottomSheet/BottomSheet.tsx index ac6f14c53..62b7ec133 100644 --- a/src/components/bottomSheet/BottomSheet.tsx +++ b/src/components/bottomSheet/BottomSheet.tsx @@ -47,7 +47,6 @@ import { SHEET_STATE, SCROLLABLE_STATE, KEYBOARD_BLUR_BEHAVIOR, - KEYBOARD_INPUT_MODE, KEYBOARD_DISMISS_THRESHOLD, SCROLLABLE_TYPE, WINDOW_HEIGHT, @@ -73,7 +72,6 @@ import { DEFAULT_ENABLE_PAN_DOWN_TO_CLOSE, INITIAL_CONTAINER_OFFSET, DEFAULT_ANIMATION_CONFIGS, - DEFAULT_KEYBOARD_INPUT_MODE, } from './constants'; import type { BottomSheetMethods, Insets } from '../../types'; import type { BottomSheetProps } from './types'; @@ -114,7 +112,6 @@ const BottomSheetComponent = forwardRef( // keyboard keyboardBehavior = DEFAULT_KEYBOARD_BEHAVIOR, keyboardBlurBehavior = DEFAULT_KEYBOARD_BLUR_BEHAVIOR, - android_keyboardInputMode = DEFAULT_KEYBOARD_INPUT_MODE, // layout handleHeight: _providedHandleHeight, @@ -285,20 +282,19 @@ const BottomSheetComponent = forwardRef( /** * Returns keyboard height that in the root container. */ - const getKeyboardHeightInContainer = useWorkletCallback(() => { - 'worklet'; - /** - * if android software input mode is not `adjustPan`, than keyboard - * height will be 0 all the time. - */ - if (android_keyboardInputMode === KEYBOARD_INPUT_MODE.adjustResize) { - return 0; - } - return $modal - ? animatedKeyboardHeight.value - - Math.abs(bottomInset - animatedContainerOffset.value.bottom) - : animatedKeyboardHeight.value - animatedContainerOffset.value.bottom; - }, [$modal, bottomInset]); + const getKeyboardHeightInContainer = useWorkletCallback( + () => + $modal + ? Math.abs( + animatedKeyboardHeight.value - + Math.abs(bottomInset - animatedContainerOffset.value.bottom) + ) + : Math.abs( + animatedKeyboardHeight.value - + animatedContainerOffset.value.bottom + ), + [$modal, bottomInset] + ); //#endregion //#region state/dynamic variables @@ -344,7 +340,7 @@ const BottomSheetComponent = forwardRef( } return SHEET_STATE.OPENED; - }); + }, [keyboardBehavior]); const animatedScrollableState = useDerivedValue(() => { /** * if sheet state is fill parent, then unlock scrolling @@ -376,76 +372,65 @@ const BottomSheetComponent = forwardRef( }); // dynamic const animatedContentHeight = useDerivedValue(() => { - const contentHeight = - animatedSheetHeight.value - animatedHandleHeight.value; - - /** - * before the container is measured, `contentHeight` value will be below zero, - * which will lead to freeze the scrollable on Android. - * - * @link (https://github.com/gorhom/react-native-bottom-sheet/issues/470) - */ - if (contentHeight <= 0) { - return 0; - } const keyboardHeightInContainer = getKeyboardHeightInContainer(); + let contentHeight = + animatedSheetHeight.value - animatedHandleHeight.value; if ( (keyboardBehavior === KEYBOARD_BEHAVIOR.none || keyboardBehavior === KEYBOARD_BEHAVIOR.extend) && animatedKeyboardState.value === KEYBOARD_STATE.SHOWN ) { - return contentHeight - keyboardHeightInContainer; - } - - if ( + contentHeight = contentHeight - keyboardHeightInContainer; + } else if ( keyboardBehavior === KEYBOARD_BEHAVIOR.fillParent && isInTemporaryPosition.value ) { if (animatedKeyboardState.value === KEYBOARD_STATE.SHOWN) { - return ( + contentHeight = animatedContainerHeight.value - animatedHandleHeight.value - - keyboardHeightInContainer - ); + keyboardHeightInContainer; + } else { + contentHeight = + animatedContainerHeight.value - animatedHandleHeight.value; } - return animatedContainerHeight.value - animatedHandleHeight.value; - } - - if ( + } else if ( keyboardBehavior === KEYBOARD_BEHAVIOR.interactive && isInTemporaryPosition.value ) { + const contentWithKeyboardHeight = + contentHeight + keyboardHeightInContainer; + if (animatedKeyboardState.value === KEYBOARD_STATE.SHOWN) { if ( keyboardHeightInContainer + animatedSheetHeight.value > animatedContainerHeight.value ) { - return ( + contentHeight = animatedContainerHeight.value - keyboardHeightInContainer - - animatedHandleHeight.value - ); + animatedHandleHeight.value; } - - return contentHeight; - } - - const contentWithKeyboardHeight = - contentHeight + keyboardHeightInContainer; - - if ( + } else if ( contentWithKeyboardHeight + animatedHandleHeight.value > animatedContainerHeight.value ) { - return animatedContainerHeight.value - animatedHandleHeight.value; + contentHeight = + animatedContainerHeight.value - animatedHandleHeight.value; + } else { + contentHeight = contentWithKeyboardHeight; } - - return contentWithKeyboardHeight; } - return contentHeight; - }); + /** + * before the container is measured, `contentHeight` value will be below zero, + * which will lead to freeze the scrollable. + * + * @link (https://github.com/gorhom/react-native-bottom-sheet/issues/470) + */ + return Math.max(contentHeight, 0); + }, [keyboardBehavior]); const animatedIndex = useDerivedValue(() => { const adjustedSnapPoints = animatedSnapPoints.value.slice().reverse(); const adjustedSnapPointsIndexes = animatedSnapPoints.value @@ -485,6 +470,7 @@ const BottomSheetComponent = forwardRef( const currentIndex = animatedCurrentIndex.value; const snapPoints = animatedSnapPoints.value; const keyboardState = animatedKeyboardState.value; + const highestSnapPoint = animatedHighestSnapPoint.value; /** * Handle restore sheet position on blur @@ -507,8 +493,7 @@ const BottomSheetComponent = forwardRef( keyboardBehavior === KEYBOARD_BEHAVIOR.extend && keyboardState === KEYBOARD_STATE.SHOWN ) { - const nextPosition = snapPoints[snapPoints.length - 1]; - return nextPosition; + return highestSnapPoint; } /** @@ -530,9 +515,12 @@ const BottomSheetComponent = forwardRef( keyboardState === KEYBOARD_STATE.SHOWN ) { isInTemporaryPosition.value = true; - const nextPosition = snapPoints[snapPoints.length - 1]; const keyboardHeightInContainer = getKeyboardHeightInContainer(); - return Math.max(0, nextPosition - keyboardHeightInContainer); + return Math.max(0, highestSnapPoint - keyboardHeightInContainer); + } + + if (isInTemporaryPosition.value) { + return animatedPosition.value; } return snapPoints[currentIndex]; @@ -550,32 +538,30 @@ const BottomSheetComponent = forwardRef( }, }); - if ( - Platform.OS === 'android' && - isInTemporaryPosition.value === false && - animatedKeyboardState.value === KEYBOARD_STATE.SHOWN - ) { - Keyboard.dismiss(); - } - if (_providedOnChange) { _providedOnChange(index); } }, - [ - _providedOnChange, - animatedCurrentIndex, - animatedKeyboardState, - isInTemporaryPosition, - ] + [_providedOnChange, animatedCurrentIndex] ); const handleOnAnimate = useCallback( - (toPoint: number) => { + function handleOnAnimate(toPoint: number) { + const snapPoints = animatedSnapPoints.value; + const toIndex = snapPoints.indexOf(toPoint); + + print({ + component: BottomSheet.name, + method: handleOnAnimate.name, + params: { + toIndex, + fromIndex: animatedCurrentIndex.value, + }, + }); + if (!_providedOnAnimate) { return; } - const snapPoints = animatedSnapPoints.value; - const toIndex = snapPoints.indexOf(toPoint); + if (toIndex !== animatedCurrentIndex.value) { _providedOnAnimate(animatedCurrentIndex.value, toIndex); } @@ -1268,12 +1254,12 @@ const BottomSheetComponent = forwardRef( animatedScrollableState, animatedKeyboardState, animatedScrollableType, - animatedKeyboardHeight, animatedIndex, animatedPosition, animatedContentHeight, animatedHandleHeight, animatedFooterHeight, + animatedKeyboardHeight, animatedContainerHeight, scrollableContentOffsetY, isInTemporaryPosition, @@ -1286,8 +1272,8 @@ const BottomSheetComponent = forwardRef( activeOffsetY: _providedActiveOffsetY, failOffsetX: _providedFailOffsetX, failOffsetY: _providedFailOffsetY, - contentPanGestureHandler, getKeyboardHeightInContainer, + contentPanGestureHandler, setScrollableRef, removeScrollableRef, }), @@ -1296,7 +1282,6 @@ const BottomSheetComponent = forwardRef( animatedPosition, animatedContentHeight, animatedScrollableType, - getKeyboardHeightInContainer, animatedFooterHeight, animatedContainerHeight, animatedHandleHeight, @@ -1304,9 +1289,6 @@ const BottomSheetComponent = forwardRef( animatedKeyboardState, animatedKeyboardHeight, animatedSheetState, - contentPanGestureHandler, - setScrollableRef, - removeScrollableRef, shouldHandleKeyboardEvents, animatedScrollableState, scrollableContentOffsetY, @@ -1320,6 +1302,10 @@ const BottomSheetComponent = forwardRef( _providedActiveOffsetY, _providedFailOffsetX, _providedFailOffsetY, + getKeyboardHeightInContainer, + contentPanGestureHandler, + setScrollableRef, + removeScrollableRef, ] ); const externalContextVariables = useMemo( @@ -1368,7 +1354,7 @@ const BottomSheetComponent = forwardRef( return { height: animate(animatedContentHeight.value, _providedAnimationConfigs), }; - }, [_providedContentHeight]); + }, [animatedContentHeight, _providedContentHeight]); const contentContainerStyle = useMemo( () => [styles.contentContainer, contentContainerAnimatedStyle], [contentContainerAnimatedStyle] @@ -1477,8 +1463,11 @@ const BottomSheetComponent = forwardRef( component: BottomSheet.name, method: 'useAnimatedReaction::OnSnapPointChange', params: { - animatedSnapPoints: _animatedSnapPoints, - prev: _previousAnimatedSnapPoints, + // animatedSnapPoints: _animatedSnapPoints, + // prev: _previousAnimatedSnapPoints, + animatedPosition: animatedPosition.value, + animatedNextPosition: animatedNextPosition.value, + animatedNextPositionIndex: animatedNextPositionIndex.value, animatedCurrentIndex: animatedCurrentIndex.value, }, }); @@ -1489,8 +1478,7 @@ const BottomSheetComponent = forwardRef( * if snap points changed while sheet is animating, then * we stop the animation and animate to the updated point. */ - if (animatedPosition.value !== animatedNextPosition.value) { - cancelAnimation(animatedPosition); + if (animatedAnimationState.value === ANIMATION_STATE.RUNNING) { nextPosition = animatedNextPositionIndex.value !== -1 ? _animatedSnapPoints[animatedNextPositionIndex.value] diff --git a/src/components/bottomSheet/constants.ts b/src/components/bottomSheet/constants.ts index 5370ed09e..49e0de68d 100644 --- a/src/components/bottomSheet/constants.ts +++ b/src/components/bottomSheet/constants.ts @@ -2,7 +2,6 @@ import Animated, { Easing } from 'react-native-reanimated'; import { KEYBOARD_BEHAVIOR, KEYBOARD_BLUR_BEHAVIOR, - KEYBOARD_INPUT_MODE, WINDOW_HEIGHT, } from '../../constants'; import { exp } from '../../utilities/easingExp'; @@ -28,7 +27,6 @@ const DEFAULT_ENABLE_PAN_DOWN_TO_CLOSE = false; const DEFAULT_ANIMATE_ON_MOUNT = false; const DEFAULT_KEYBOARD_BEHAVIOR = KEYBOARD_BEHAVIOR.none; const DEFAULT_KEYBOARD_BLUR_BEHAVIOR = KEYBOARD_BLUR_BEHAVIOR.none; -const DEFAULT_KEYBOARD_INPUT_MODE = KEYBOARD_INPUT_MODE.adjustPan; // initial values const INITIAL_SNAP_POINT = -999; @@ -55,7 +53,6 @@ export { DEFAULT_ANIMATE_ON_MOUNT, DEFAULT_KEYBOARD_BEHAVIOR, DEFAULT_KEYBOARD_BLUR_BEHAVIOR, - DEFAULT_KEYBOARD_INPUT_MODE, // initial INITIAL_POSITION, INITIAL_CONTAINER_HEIGHT, diff --git a/src/components/bottomSheet/types.d.ts b/src/components/bottomSheet/types.d.ts index 3d25a2519..3de2779ef 100644 --- a/src/components/bottomSheet/types.d.ts +++ b/src/components/bottomSheet/types.d.ts @@ -8,7 +8,6 @@ import type { BottomSheetBackgroundProps } from '../bottomSheetBackground'; import type { KEYBOARD_BEHAVIOR, KEYBOARD_BLUR_BEHAVIOR, - KEYBOARD_INPUT_MODE, } from '../../constants'; export interface BottomSheetProps @@ -153,13 +152,6 @@ export interface BottomSheetProps * - `restore`: restore sheet position. */ keyboardBlurBehavior?: keyof typeof KEYBOARD_BLUR_BEHAVIOR; - /** - * Defines keyboard input mode for Android only. - * @link {https://developer.android.com/guide/topics/manifest/activity-element#wsoft} - * @type `adjustPan` | `adjustResize` - * @default `adjustPan` - */ - android_keyboardInputMode?: keyof typeof KEYBOARD_INPUT_MODE; //#endregion /** diff --git a/src/components/bottomSheetDebugView/styles.ts b/src/components/bottomSheetDebugView/styles.ts index 3ad37cbf6..831ed82be 100644 --- a/src/components/bottomSheetDebugView/styles.ts +++ b/src/components/bottomSheetDebugView/styles.ts @@ -4,13 +4,14 @@ export const styles = StyleSheet.create({ container: { position: 'absolute', right: 4, - top: 50, + top: 0, padding: 2, - backgroundColor: 'rgba(0, 0,0,0.75)', + backgroundColor: 'rgba(0, 0,0,0.5)', }, text: { - fontSize: 16, - lineHeight: 20, + fontSize: 14, + lineHeight: 16, + textAlignVertical: 'center', height: 20, padding: 0, color: 'white', diff --git a/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx b/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx index 764177d23..c25144e55 100644 --- a/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx +++ b/src/components/bottomSheetHandleContainer/BottomSheetHandleContainer.tsx @@ -101,6 +101,7 @@ function BottomSheetHandleContainerComponent({ onGestureEvent={handlePanGestureHandler} >