@attio/react-native-bottom-sheet-toolbox
Version:
73 lines (70 loc) • 3.44 kB
JavaScript
;
import { useDerivedValue } from "react-native-reanimated";
import { useBottomSheetToolboxInternalContext, useKeyboardHeightSharedValue } from "../context";
import { useFooterFreezeWhenExpanding } from "./use-footer-freeze-when-expanding";
import { useLastSharedValueBeforeLock } from "./use-last-shared-value-before-lock";
/**
* A shared value used as the bottom position for a footer.
*/
export function useFooterBottomPositionSharedValue({
bufferSharedValue: outerBufferSharedValue,
disableKeyboardAdjust = false,
freezeWhenExpanding = true
}) {
const {
isReadySharedValue,
currentPositionSharedValue,
childrenHeightSharedValue,
wrapperHeightSharedValue,
footerHeightSharedValue
} = useBottomSheetToolboxInternalContext();
const keyboardHeightSharedValue = useKeyboardHeightSharedValue();
const bufferSharedValue = useDerivedValue(() => {
if (outerBufferSharedValue) return outerBufferSharedValue.get();
const childrenHeight = childrenHeightSharedValue.get();
const wrapperHeight = wrapperHeightSharedValue.get();
const footerHeight = footerHeightSharedValue.get();
if (childrenHeight === null || wrapperHeight === null || footerHeight === null) {
return null;
}
return Math.min(childrenHeight, wrapperHeight - footerHeight);
}, [outerBufferSharedValue, childrenHeightSharedValue, wrapperHeightSharedValue, footerHeightSharedValue]);
const rawBottomSharedValue = useDerivedValue(() => {
const footerHeight = footerHeightSharedValue.get();
const buffer = bufferSharedValue.get();
if (!isReadySharedValue.get() || buffer === null || footerHeight === null) {
return null;
}
const keyboardAdjust = disableKeyboardAdjust ? 0 : keyboardHeightSharedValue.get();
const unclampedClosingOffset = currentPositionSharedValue.get() - footerHeight - buffer - keyboardAdjust;
const closingOffset = Math.min(0, unclampedClosingOffset);
const bottom = keyboardAdjust + closingOffset;
return bottom;
}, [isReadySharedValue, currentPositionSharedValue, disableKeyboardAdjust, footerHeightSharedValue, keyboardHeightSharedValue]);
const bottomAtTimeOfLockSharedValue = useLastSharedValueBeforeLock(rawBottomSharedValue);
const freezeWhenExpandingSharedValue = useFooterFreezeWhenExpanding({
bufferSharedValue,
bottomAtTimeOfLockSharedValue
});
/**
* 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.
*/
const frozenBottomSharedValue = useDerivedValue(() => {
const bottom = rawBottomSharedValue.get();
const bottomAtTimeOfLock = bottomAtTimeOfLockSharedValue.get();
const shouldFreezeBottom = freezeWhenExpanding && freezeWhenExpandingSharedValue.get();
return shouldFreezeBottom ? bottomAtTimeOfLock ?? bottom : bottom;
}, [bottomAtTimeOfLockSharedValue, freezeWhenExpanding, freezeWhenExpandingSharedValue]);
/**
* Note: returning different SharedValue references doesn't play well with
* useAnimatedStyle. Hence we always return the derived value.
*/
return frozenBottomSharedValue;
}
//# sourceMappingURL=use-footer-bottom-position-shared-value.js.map