UNPKG

@attio/react-native-bottom-sheet-toolbox

Version:
84 lines (80 loc) 3.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useBottomSheetSnapWhenIdle = useBottomSheetSnapWhenIdle; var _reactNativeReanimated = require("react-native-reanimated"); var _context = require("../context"); var _utils = require("../utils"); var _useBottomSheetPositionLock = require("./use-bottom-sheet-position-lock"); const LOCK_ID = "useBottomSheetSnapWhenIdle"; /** * This hook snaps the bottom sheet to the nearest snap point when * nothing else is interacting with it. It takes into account the * last known velocity. * * A snap is triggered after either of the following two conditions: * - The position off any snap-point, and has been released. * - The underlying snap-points have changed. */ function useBottomSheetSnapWhenIdle() { const { currentPositionSharedValue, currentPositionLastVelocitySharedValue, currentPositionDestinationSharedValue, normalizedSnapPointsSharedValue, isReadySharedValue, currentPositionLockSharedValue } = (0, _context.useBottomSheetToolboxInternalContext)(); const { canLockSharedValue, hasLockSharedValue, lock, release, setPositionAnimate, setVelocity } = (0, _useBottomSheetPositionLock.useBottomSheetPositionLock)(LOCK_ID, _utils.BottomSheetPositionBuiltInLockPriority.SNAP_WHEN_IDLE); const lastSnapPointIndexSharedValue = (0, _reactNativeReanimated.useSharedValue)(-1); (0, _reactNativeReanimated.useAnimatedReaction)(() => ({ canLock: isReadySharedValue.get() && canLockSharedValue.get(), hasLock: hasLockSharedValue.get(), snapPoints: normalizedSnapPointsSharedValue.get() }), ({ canLock, hasLock, snapPoints }, lastResults) => { const canLockOrHasLock = canLock || hasLock; if (!snapPoints || !canLockOrHasLock) { lastSnapPointIndexSharedValue.set(-1); return; } const lastCanLockOrHasLock = lastResults?.canLock || lastResults?.hasLock; const didLockStatusChange = lastCanLockOrHasLock !== canLockOrHasLock; const lastSnapPoints = lastResults?.snapPoints || []; const didSnapPointsChange = snapPoints === null ? lastSnapPoints === null : lastSnapPoints.length !== snapPoints.length || lastSnapPoints.some((v, index) => v !== snapPoints[index]); // Nothing to do if (!didLockStatusChange && !didSnapPointsChange) return; /** * If our snap-points change, then try to follow the snap-point we * were last at. This also supports the case where the snap-points * are updated to be equal, but then separate again. That case can * happen when the keyboard opens. */ lastSnapPointIndexSharedValue.set(lastSnapPoints.indexOf(currentPositionDestinationSharedValue.get())); const currentPosition = currentPositionSharedValue.get(); const point = lastSnapPointIndexSharedValue.get() === -1 ? (0, _utils.snapPoint)(currentPosition, currentPositionLastVelocitySharedValue.get(), snapPoints) : snapPoints[lastSnapPointIndexSharedValue.get()] ?? null; if (point === null || point === currentPosition) return; if (!hasLock) { lock(); } setPositionAnimate(point, undefined, finished => { const currentPositionLock = currentPositionLockSharedValue.get(); if (finished || currentPositionLock?.id !== LOCK_ID) { release(); } }); setVelocity(0); }, [canLockSharedValue, hasLockSharedValue, normalizedSnapPointsSharedValue, isReadySharedValue.get]); } //# sourceMappingURL=use-bottom-sheet-snap-when-idle.js.map