@gorhom/bottom-sheet
Version:
A performant interactive bottom sheet with fully configurable options 🚀
95 lines (84 loc) • 3.98 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useAnimatedDetents = void 0;
var _reactNativeReanimated = require("react-native-reanimated");
var _constants = require("../constants");
var _utilities = require("../utilities");
/**
* A custom hook that computes and returns the animated detent positions for a bottom sheet component.
*
* This hook normalizes the provided snap points (detents), optionally adds a dynamic detent based on content size,
* and calculates key positions such as the highest detent and the closed position. It supports both static and dynamic
* sizing, and adapts to modal and detached sheet modes.
*
* @param detents - The snap points for the bottom sheet, which can be an array or an object with a `value` property.
* @param layoutState - A shared animated value containing the current layout state (container, handle, and content heights).
* @param enableDynamicSizing - Whether dynamic sizing based on content height is enabled.
* @param maxDynamicContentSize - The maximum allowed content size for dynamic sizing.
* @param detached - Whether the bottom sheet is in detached mode.
* @param $modal - Whether the bottom sheet is presented as a modal.
* @param bottomInset - The bottom inset to apply when the sheet is modal or detached (default is 0).
*/
const useAnimatedDetents = (detents, layoutState, enableDynamicSizing, maxDynamicContentSize, detached, $modal, bottomInset = 0) => {
const state = (0, _reactNativeReanimated.useDerivedValue)(() => {
const {
containerHeight,
handleHeight,
contentHeight
} = layoutState.get();
// early exit, if container layout is not ready
if (containerHeight === _constants.INITIAL_LAYOUT_VALUE) {
return {};
}
// extract detents from provided props
const _detents = detents ? 'value' in detents ? detents.value : detents : [];
// normalized all provided detents, converting percentage
// values into absolute values.
let _normalizedDetents = _detents.map(snapPoint => (0, _utilities.normalizeSnapPoint)(snapPoint, containerHeight));
let highestDetentPosition = _normalizedDetents[_normalizedDetents.length - 1];
let closedDetentPosition = containerHeight;
if ($modal || detached) {
closedDetentPosition = containerHeight + bottomInset;
}
if (!enableDynamicSizing) {
return {
detents: _normalizedDetents,
highestDetentPosition,
closedDetentPosition
};
}
// early exit, if dynamic sizing is enabled and
// content height is not calculated yet.
if (contentHeight === _constants.INITIAL_LAYOUT_VALUE) {
return {};
}
// early exit, if handle height is not calculated yet.
if (handleHeight === _constants.INITIAL_LAYOUT_VALUE) {
return {};
}
// calculate a new detents based on content height.
const dynamicSnapPoint = containerHeight - Math.min(contentHeight + handleHeight, maxDynamicContentSize !== undefined ? maxDynamicContentSize : containerHeight);
// push dynamic detent into the normalized detents,
// only if it does not exists in the provided list already.
if (!_normalizedDetents.includes(dynamicSnapPoint)) {
_normalizedDetents.push(dynamicSnapPoint);
}
// sort all detents.
_normalizedDetents = _normalizedDetents.sort((a, b) => b - a);
// update the highest detent position.
highestDetentPosition = _normalizedDetents[_normalizedDetents.length - 1];
// locate the dynamic detent index.
const dynamicDetentIndex = _normalizedDetents.indexOf(dynamicSnapPoint);
return {
detents: _normalizedDetents,
dynamicDetentIndex,
highestDetentPosition,
closedDetentPosition
};
}, [detents, layoutState, enableDynamicSizing, maxDynamicContentSize, detached, $modal, bottomInset]);
return state;
};
exports.useAnimatedDetents = useAnimatedDetents;
//# sourceMappingURL=useAnimatedDetents.js.map
;