UNPKG

@gorhom/bottom-sheet

Version:

A performant interactive bottom sheet with fully configurable options 🚀

91 lines (80 loc) • 3.38 kB
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