@gorhom/bottom-sheet
Version:
A performant interactive bottom sheet with fully configurable options 🚀
91 lines (80 loc) • 3.38 kB
JavaScript
import React, { memo, useCallback, useMemo, useRef } from 'react';
import Animated, { interpolate, Extrapolate, useAnimatedStyle, useAnimatedReaction, useAnimatedGestureHandler, runOnJS } from 'react-native-reanimated';
import { TapGestureHandler } from 'react-native-gesture-handler';
import { useBottomSheet } from '../../hooks';
import { DEFAULT_OPACITY, DEFAULT_APPEARS_ON_INDEX, DEFAULT_DISAPPEARS_ON_INDEX, DEFAULT_ENABLE_TOUCH_THROUGH, DEFAULT_PRESS_BEHAVIOR } from './constants';
import { styles } from './styles';
const BottomSheetBackdropComponent = ({
animatedIndex,
opacity = DEFAULT_OPACITY,
appearsOnIndex = DEFAULT_APPEARS_ON_INDEX,
disappearsOnIndex = DEFAULT_DISAPPEARS_ON_INDEX,
enableTouchThrough = DEFAULT_ENABLE_TOUCH_THROUGH,
pressBehavior = DEFAULT_PRESS_BEHAVIOR,
style,
children
}) => {
//#region hooks
const {
snapToIndex,
close
} = useBottomSheet(); //#endregion
//#region variables
const containerRef = useRef(null);
const pointerEvents = enableTouchThrough ? 'none' : 'auto'; //#endregion
//#region callbacks
const handleOnPress = useCallback(() => {
if (pressBehavior === 'close') {
close();
} else if (pressBehavior === 'collapse') {
snapToIndex(disappearsOnIndex);
} else if (typeof pressBehavior === 'number') {
snapToIndex(pressBehavior);
}
}, [snapToIndex, close, disappearsOnIndex, pressBehavior]);
const handleContainerTouchability = useCallback(shouldDisableTouchability => {
if (!containerRef.current) {
return;
} // @ts-ignore
containerRef.current.setNativeProps({
pointerEvents: shouldDisableTouchability ? 'none' : 'auto'
});
}, []); //#endregion
//#region tap gesture
const gestureHandler = useAnimatedGestureHandler({
onFinish: () => {
runOnJS(handleOnPress)();
}
}, [handleOnPress]); //#endregion
//#region styles
const containerAnimatedStyle = useAnimatedStyle(() => ({
opacity: interpolate(animatedIndex.value, [-1, disappearsOnIndex, appearsOnIndex], [0, 0, opacity], Extrapolate.CLAMP),
flex: 1
}));
const containerStyle = useMemo(() => [styles.container, style, containerAnimatedStyle], [style, containerAnimatedStyle]); //#endregion
//#region effects
useAnimatedReaction(() => animatedIndex.value <= disappearsOnIndex, (shouldDisableTouchability, previous) => {
if (shouldDisableTouchability === previous) {
return;
}
runOnJS(handleContainerTouchability)(shouldDisableTouchability);
}, [disappearsOnIndex]); //#endregion
return pressBehavior !== 'none' ? /*#__PURE__*/React.createElement(TapGestureHandler, {
onGestureEvent: gestureHandler
}, /*#__PURE__*/React.createElement(Animated.View, {
ref: containerRef,
style: containerStyle,
accessible: true,
accessibilityRole: "button",
accessibilityLabel: "Bottom Sheet backdrop",
accessibilityHint: `Tap to ${typeof pressBehavior === 'string' ? pressBehavior : 'move'} the Bottom Sheet`
}, children)) : /*#__PURE__*/React.createElement(Animated.View, {
ref: containerRef,
pointerEvents: pointerEvents,
style: containerStyle
}, children);
};
const BottomSheetBackdrop = /*#__PURE__*/memo(BottomSheetBackdropComponent);
BottomSheetBackdrop.displayName = 'BottomSheetBackdrop';
export default BottomSheetBackdrop;
//# sourceMappingURL=BottomSheetBackdrop.js.map