@@ -47,6 +47,7 @@ import {
4747 usePropsValidator ,
4848 useReactiveSharedValue ,
4949 useScrollable ,
50+ useStableCallback ,
5051} from '../../hooks' ;
5152import type { BottomSheetMethods } from '../../types' ;
5253import {
@@ -69,6 +70,7 @@ import {
6970 DEFAULT_ACCESSIBLE ,
7071 DEFAULT_ANIMATE_ON_MOUNT ,
7172 DEFAULT_DYNAMIC_SIZING ,
73+ DEFAULT_ENABLE_BLUR_KEYBOARD_ON_GESTURE ,
7274 DEFAULT_ENABLE_CONTENT_PANNING_GESTURE ,
7375 DEFAULT_ENABLE_OVER_DRAG ,
7476 DEFAULT_ENABLE_PAN_DOWN_TO_CLOSE ,
@@ -125,6 +127,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
125127 keyboardBehavior = DEFAULT_KEYBOARD_BEHAVIOR ,
126128 keyboardBlurBehavior = DEFAULT_KEYBOARD_BLUR_BEHAVIOR ,
127129 android_keyboardInputMode = DEFAULT_KEYBOARD_INPUT_MODE ,
130+ enableBlurKeyboardOnGesture = DEFAULT_ENABLE_BLUR_KEYBOARD_ON_GESTURE ,
128131
129132 // layout
130133 containerHeight : _providedContainerHeight ,
@@ -245,7 +248,9 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
245248 const animatedNextPositionIndex = useSharedValue ( INITIAL_VALUE ) ;
246249
247250 // conditional
248- const isAnimatedOnMount = useSharedValue ( false ) ;
251+ const isAnimatedOnMount = useSharedValue (
252+ ! animateOnMount || _providedIndex === - 1
253+ ) ;
249254 const isContentHeightFixed = useSharedValue ( false ) ;
250255 const isLayoutCalculated = useDerivedValue ( ( ) => {
251256 let isContainerHeightCalculated = false ;
@@ -674,6 +679,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
674679 params : {
675680 currentPosition : animatedPosition . value ,
676681 nextPosition : position ,
682+ source,
677683 } ,
678684 } ) ;
679685 }
@@ -1017,68 +1023,56 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
10171023 //#endregion
10181024
10191025 //#region public methods
1020- // biome-ignore lint/correctness/useExhaustiveDependencies(BottomSheet.name): used for debug only
1021- const handleSnapToIndex = useCallback (
1022- function handleSnapToIndex (
1023- index : number ,
1024- animationConfigs ?: WithSpringConfig | WithTimingConfig
1025- ) {
1026- const snapPoints = animatedSnapPoints . value ;
1027- invariant (
1028- index >= - 1 && index <= snapPoints . length - 1 ,
1029- `'index' was provided but out of the provided snap points range! expected value to be between -1, ${
1030- snapPoints . length - 1
1031- } `
1032- ) ;
1033- if ( __DEV__ ) {
1034- print ( {
1035- component : BottomSheet . name ,
1036- method : handleSnapToIndex . name ,
1037- params : {
1038- index,
1039- } ,
1040- } ) ;
1041- }
1026+ const handleSnapToIndex = useStableCallback ( function handleSnapToIndex (
1027+ index : number ,
1028+ animationConfigs ?: WithSpringConfig | WithTimingConfig
1029+ ) {
1030+ const snapPoints = animatedSnapPoints . value ;
1031+ invariant (
1032+ index >= - 1 && index <= snapPoints . length - 1 ,
1033+ `'index' was provided but out of the provided snap points range! expected value to be between -1, ${
1034+ snapPoints . length - 1
1035+ } `
1036+ ) ;
1037+ if ( __DEV__ ) {
1038+ print ( {
1039+ component : BottomSheet . name ,
1040+ method : handleSnapToIndex . name ,
1041+ params : {
1042+ index,
1043+ } ,
1044+ } ) ;
1045+ }
10421046
1043- const nextPosition = snapPoints [ index ] ;
1047+ const nextPosition = snapPoints [ index ] ;
10441048
1045- /**
1046- * exit method if :
1047- * - layout is not calculated.
1048- * - already animating to next position.
1049- * - sheet is forced closing.
1050- */
1051- if (
1052- ! isLayoutCalculated . value ||
1053- index === animatedNextPositionIndex . value ||
1054- nextPosition === animatedNextPosition . value ||
1055- isForcedClosing . value
1056- ) {
1057- return ;
1058- }
1049+ /**
1050+ * exit method if :
1051+ * - layout is not calculated.
1052+ * - already animating to next position.
1053+ * - sheet is forced closing.
1054+ */
1055+ if (
1056+ ! isLayoutCalculated . value ||
1057+ index === animatedNextPositionIndex . value ||
1058+ nextPosition === animatedNextPosition . value ||
1059+ isForcedClosing . value
1060+ ) {
1061+ return ;
1062+ }
10591063
1060- /**
1061- * reset temporary position boolean.
1062- */
1063- isInTemporaryPosition . value = false ;
1064+ /**
1065+ * reset temporary position boolean.
1066+ */
1067+ isInTemporaryPosition . value = false ;
10641068
1065- runOnUI ( animateToPosition ) (
1066- nextPosition ,
1067- ANIMATION_SOURCE . USER ,
1068- 0 ,
1069- animationConfigs
1070- ) ;
1071- } ,
1072- [
1073- animateToPosition ,
1074- isLayoutCalculated ,
1075- isInTemporaryPosition ,
1076- isForcedClosing ,
1077- animatedSnapPoints ,
1078- animatedNextPosition ,
1079- animatedNextPositionIndex ,
1080- ]
1081- ) ;
1069+ runOnUI ( animateToPosition ) (
1070+ nextPosition ,
1071+ ANIMATION_SOURCE . USER ,
1072+ 0 ,
1073+ animationConfigs
1074+ ) ;
1075+ } ) ;
10821076 const handleSnapToPosition = useWorkletCallback (
10831077 function handleSnapToPosition (
10841078 position : number | string ,
@@ -1390,6 +1384,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
13901384 activeOffsetY : _providedActiveOffsetY ,
13911385 failOffsetX : _providedFailOffsetX ,
13921386 failOffsetY : _providedFailOffsetY ,
1387+ enableBlurKeyboardOnGesture,
13931388 animateToPosition,
13941389 stopAnimation,
13951390 setScrollableRef,
@@ -1425,6 +1420,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
14251420 enableOverDrag ,
14261421 enablePanDownToClose ,
14271422 enableDynamicSizing ,
1423+ enableBlurKeyboardOnGesture ,
14281424 _providedSimultaneousHandlers ,
14291425 _providedWaitFor ,
14301426 _providedActiveOffsetX ,
@@ -1538,6 +1534,25 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
15381534 }
15391535
15401536 animatedContainerHeightDidChange . value = result !== previous ;
1537+
1538+ /**
1539+ * When user close the bottom sheet while the keyboard open on Android with
1540+ * software keyboard layout mode set to resize, the close position would be
1541+ * set to the container height - the keyboard height, and when the keyboard
1542+ * closes, the container height and here we restart the animation again.
1543+ *
1544+ * [read more](https://github.com/gorhom/react-native-bottom-sheet/issues/2163)
1545+ */
1546+ if (
1547+ animatedAnimationState . value === ANIMATION_STATE . RUNNING &&
1548+ animatedAnimationSource . value === ANIMATION_SOURCE . GESTURE &&
1549+ animatedNextPositionIndex . value === - 1
1550+ ) {
1551+ animateToPosition (
1552+ animatedClosedPosition . value ,
1553+ ANIMATION_SOURCE . GESTURE
1554+ ) ;
1555+ }
15411556 }
15421557 ) ;
15431558
@@ -1860,10 +1875,13 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
18601875 * @alias onIndexChange
18611876 */
18621877 useEffect ( ( ) => {
1863- if ( isAnimatedOnMount . value ) {
1864- handleSnapToIndex ( _providedIndex ) ;
1878+ // early exit, if animate on mount is set and it did not animate yet.
1879+ if ( animateOnMount && ! isAnimatedOnMount . value ) {
1880+ return ;
18651881 }
1866- } , [ _providedIndex , isAnimatedOnMount , handleSnapToIndex ] ) ;
1882+
1883+ handleSnapToIndex ( _providedIndex ) ;
1884+ } , [ animateOnMount , _providedIndex , isAnimatedOnMount , handleSnapToIndex ] ) ;
18671885 //#endregion
18681886
18691887 // render
0 commit comments