@attio/react-native-bottom-sheet-toolbox
Version:
62 lines (59 loc) • 3 kB
JavaScript
;
import { PixelRatio } from "react-native";
import { useAnimatedReaction, useDerivedValue } from "react-native-reanimated";
import { useBottomSheetToolboxInternalContext, useKeyboardProgressSharedValue } from "../context";
import { useLastSharedValueBeforeLock } from "./use-last-shared-value-before-lock";
/**
* Returns a shared value that tells the footer whether it should freeze its
* position as the content is expanding.
*/
export function useFooterFreezeWhenExpanding({
bufferSharedValue,
bottomAtTimeOfLockSharedValue
}) {
const {
currentPositionDestinationSharedValue
} = useBottomSheetToolboxInternalContext();
const keyboardProgressSharedValue = useKeyboardProgressSharedValue();
const lastBufferSharedValue = useLastSharedValueBeforeLock(bufferSharedValue);
const pixelRatio = PixelRatio.get();
useAnimatedReaction(() => currentPositionDestinationSharedValue.get(), (destination, lastDestination) => {
const lastBuffer = lastBufferSharedValue.get();
if (lastBuffer !== null) {
const destinationDiff = destination - (lastDestination ?? 0);
const destinationDiffRounded = Math.round(destinationDiff * pixelRatio) / pixelRatio;
if (destinationDiffRounded < -1) {
lastBufferSharedValue.set(bufferSharedValue.get());
}
}
}, [currentPositionDestinationSharedValue]);
const isExpandingSharedValue = useDerivedValue(() => {
const buffer = bufferSharedValue.get();
const lastBuffer = lastBufferSharedValue.get();
const delta = buffer === null || lastBuffer === null ? null : buffer - lastBuffer;
return delta !== null && delta > 0;
}, [lastBufferSharedValue, bufferSharedValue.get]);
// This happens when opening and quickly closing.
const wasMovingWithSheetSharedValue = useDerivedValue(() => {
const bottomAtTimeOfLock = bottomAtTimeOfLockSharedValue.get();
const roundedBottom = bottomAtTimeOfLock !== null ? Math.round(bottomAtTimeOfLock * pixelRatio) / pixelRatio : null;
return roundedBottom !== null && roundedBottom < 0;
}, [bottomAtTimeOfLockSharedValue, pixelRatio]);
const isKeyboardMovingSharedValue = useDerivedValue(() => keyboardProgressSharedValue.get() !== 0 && keyboardProgressSharedValue.get() !== 1, [keyboardProgressSharedValue]);
/**
* If the content-size of the sheet increases, then we actually want the
* footer to stay where it is (not shift down as if it's animating back in).
*
*
* To determine this, we snapshot the sheet position at the time of the lock
* and see if we're expanding up or down. We also keep a snapshot of the
* bottom right before the lock was engaged.
*/
return useDerivedValue(() => {
const wasMovingWithSheet = wasMovingWithSheetSharedValue.get();
const isSettled = !wasMovingWithSheet && !isKeyboardMovingSharedValue.get();
const isExpanding = isExpandingSharedValue.get();
return isExpanding && isSettled;
}, []);
}
//# sourceMappingURL=use-footer-freeze-when-expanding.js.map