Skip to content

Commit ed75bb7

Browse files
committed
fix: fixed position x index sequencing with container resizing (gorhom#1675)
gorhom@f0ec705
1 parent afb2f9f commit ed75bb7

File tree

2 files changed

+73
-20
lines changed

2 files changed

+73
-20
lines changed

src/components/bottomSheet/BottomSheet.tsx

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -713,9 +713,9 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
713713
method: animateToPosition.name,
714714
params: {
715715
currentPosition: animatedPosition.value,
716-
position,
716+
nextPosition: position,
717717
velocity,
718-
animatedContainerHeight: animatedContainerHeight.value,
718+
source,
719719
},
720720
});
721721

@@ -763,6 +763,47 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
763763
},
764764
[handleOnAnimate, _providedAnimationConfigs]
765765
);
766+
/**
767+
* Set to position without animation.
768+
*
769+
* @param targetPosition position to be set.
770+
*/
771+
const setToPosition = useWorkletCallback(function setToPosition(
772+
targetPosition: number
773+
) {
774+
if (
775+
targetPosition === animatedPosition.value ||
776+
targetPosition === undefined ||
777+
(animatedAnimationState.value === ANIMATION_STATE.RUNNING &&
778+
targetPosition === animatedNextPosition.value)
779+
) {
780+
return;
781+
}
782+
783+
runOnJS(print)({
784+
component: BottomSheet.name,
785+
method: setToPosition.name,
786+
params: {
787+
currentPosition: animatedPosition.value,
788+
targetPosition,
789+
},
790+
});
791+
792+
/**
793+
* store next position
794+
*/
795+
animatedNextPosition.value = targetPosition;
796+
animatedNextPositionIndex.value =
797+
animatedSnapPoints.value.indexOf(targetPosition);
798+
799+
stopAnimation();
800+
801+
/**
802+
* set position.
803+
*/
804+
animatedPosition.value = targetPosition;
805+
},
806+
[]);
766807
//#endregion
767808

768809
//#region public methods
@@ -1343,16 +1384,8 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
13431384
animatedNextPositionIndex.value === -1 &&
13441385
_previousContainerHeight !== containerHeight
13451386
) {
1346-
animationSource = ANIMATION_SOURCE.CONTAINER_RESIZE;
1347-
animationConfig = {
1348-
duration: 0,
1349-
};
1350-
animateToPosition(
1351-
containerHeight,
1352-
animationSource,
1353-
0,
1354-
animationConfig
1355-
);
1387+
setToPosition(containerHeight);
1388+
return;
13561389
}
13571390

13581391
if (
@@ -1393,13 +1426,11 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
13931426

13941427
/**
13951428
* if snap points changes because of the container height change,
1396-
* then we skip the snap animation by setting the duration to 0.
1429+
* then we set the new position without animation.
13971430
*/
13981431
if (containerHeight !== _previousContainerHeight) {
1399-
animationSource = ANIMATION_SOURCE.CONTAINER_RESIZE;
1400-
animationConfig = {
1401-
duration: 0,
1402-
};
1432+
setToPosition(nextPosition);
1433+
return;
14031434
}
14041435
}
14051436
animateToPosition(nextPosition, animationSource, 0, animationConfig);
@@ -1553,6 +1584,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
15531584
}),
15541585
({
15551586
_animatedIndex,
1587+
_animatedPosition,
15561588
_animationState,
15571589
_contentGestureState,
15581590
_handleGestureState,
@@ -1564,6 +1596,21 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
15641596
return;
15651597
}
15661598

1599+
/**
1600+
* exit the method if index value is not synced with
1601+
* position value.
1602+
*
1603+
* [read more](https://github.com/gorhom/react-native-bottom-sheet/issues/1356)
1604+
*/
1605+
if (
1606+
animatedNextPosition.value !== INITIAL_VALUE &&
1607+
animatedNextPositionIndex.value !== INITIAL_VALUE &&
1608+
(_animatedPosition !== animatedNextPosition.value ||
1609+
_animatedIndex !== animatedNextPositionIndex.value)
1610+
) {
1611+
return;
1612+
}
1613+
15671614
/**
15681615
* exit the method if animated index value
15691616
* has fraction, e.g. 1.99, 0.52

src/hooks/useBottomSheetTimingConfigs.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
import { useMemo } from 'react';
2-
import type { WithTimingConfig } from 'react-native-reanimated';
2+
import type { EasingFunction } from 'react-native';
3+
import type { EasingFunctionFactory } from 'react-native-reanimated';
34
import { ANIMATION_DURATION, ANIMATION_EASING } from '../constants';
45

6+
interface TimingConfig {
7+
duration?: number;
8+
easing?: EasingFunction | EasingFunctionFactory;
9+
}
10+
511
/**
612
* Generate timing animation configs.
713
* @default
814
* - easing: Easing.out(Easing.exp)
915
* - duration 250
1016
* @param configs overridable configs.
1117
*/
12-
export const useBottomSheetTimingConfigs = (configs: WithTimingConfig) => {
18+
export const useBottomSheetTimingConfigs = (configs: TimingConfig) => {
1319
return useMemo(() => {
14-
const _configs: WithTimingConfig = {
20+
const _configs: TimingConfig = {
1521
easing: configs.easing || ANIMATION_EASING,
1622
duration: configs.duration || ANIMATION_DURATION,
1723
};

0 commit comments

Comments
 (0)