UNPKG

@gorhom/bottom-sheet

Version:

A performant interactive bottom sheet with fully configurable options 🚀

115 lines (108 loc) • 4.73 kB
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } import React, { forwardRef, useContext, useImperativeHandle, useMemo } from 'react'; import { Gesture } from 'react-native-gesture-handler'; import { useAnimatedProps, useAnimatedStyle } from 'react-native-reanimated'; import { SCROLLABLE_DECELERATION_RATE_MAPPER, SCROLLABLE_STATE } from '../../constants'; import { BottomSheetDraggableContext } from '../../contexts/gesture'; import { useBottomSheetInternal, useScrollHandler, useScrollableSetter, useStableCallback } from '../../hooks'; import { ScrollableContainer } from './ScrollableContainer'; import { useBottomSheetContentSizeSetter } from './useBottomSheetContentSizeSetter'; export function createBottomSheetScrollableComponent(type, // biome-ignore lint: to be addressed! ScrollableComponent) { return /*#__PURE__*/forwardRef((props, ref) => { //#region props const { // hooks focusHook, scrollEventsHandlersHook, // props enableFooterMarginAdjustment = false, overScrollMode = 'never', keyboardDismissMode = 'interactive', showsVerticalScrollIndicator = true, style, refreshing, onRefresh, progressViewOffset, refreshControl, // events onScroll, onScrollBeginDrag, onScrollEndDrag, onContentSizeChange, ...rest // biome-ignore lint: to be addressed! } = props; //#endregion //#region hooks const draggableGesture = useContext(BottomSheetDraggableContext); const { scrollableRef, scrollableContentOffsetY, scrollHandler } = useScrollHandler(scrollEventsHandlersHook, onScroll, onScrollBeginDrag, onScrollEndDrag); const { animatedFooterHeight, animatedScrollableState, enableContentPanningGesture } = useBottomSheetInternal(); const { setContentSize } = useBottomSheetContentSizeSetter(enableFooterMarginAdjustment); //#endregion if (!draggableGesture && enableContentPanningGesture) { throw "'Scrollable' cannot be used out of the BottomSheet!"; } //#region variables const scrollableAnimatedProps = useAnimatedProps(() => ({ decelerationRate: SCROLLABLE_DECELERATION_RATE_MAPPER[animatedScrollableState.value], showsVerticalScrollIndicator: showsVerticalScrollIndicator ? animatedScrollableState.value === SCROLLABLE_STATE.UNLOCKED : showsVerticalScrollIndicator }), [animatedScrollableState, showsVerticalScrollIndicator]); const scrollableGesture = useMemo(() => draggableGesture ? Gesture.Native() // @ts-ignore .simultaneousWithExternalGesture(draggableGesture).shouldCancelWhenOutside(false) : undefined, [draggableGesture]); //#endregion //#region callbacks const handleContentSizeChange = useStableCallback((contentWidth, contentHeight) => { setContentSize(contentHeight); if (onContentSizeChange) { onContentSizeChange(contentWidth, contentHeight); } }); //#endregion //#region styles const containerAnimatedStyle = useAnimatedStyle(() => ({ marginBottom: enableFooterMarginAdjustment ? animatedFooterHeight.value : 0 }), [animatedFooterHeight.value, enableFooterMarginAdjustment]); const containerStyle = useMemo(() => { return enableFooterMarginAdjustment ? [...(style ? 'length' in style ? style : [style] : []), containerAnimatedStyle] : style; }, [enableFooterMarginAdjustment, style, containerAnimatedStyle]); //#endregion //#region effects // @ts-ignore useImperativeHandle(ref, () => scrollableRef.current); useScrollableSetter(scrollableRef, type, scrollableContentOffsetY, onRefresh !== undefined, focusHook); //#endregion //#region render return /*#__PURE__*/React.createElement(ScrollableContainer, _extends({ ref: scrollableRef, nativeGesture: scrollableGesture, animatedProps: scrollableAnimatedProps, overScrollMode: overScrollMode, keyboardDismissMode: keyboardDismissMode, refreshing: refreshing, scrollEventThrottle: 16, progressViewOffset: progressViewOffset, style: containerStyle, onRefresh: onRefresh, onScroll: scrollHandler, onContentSizeChange: handleContentSizeChange, setContentSize: setContentSize, ScrollableComponent: ScrollableComponent, refreshControl: refreshControl }, rest)); //#endregion }); } //# sourceMappingURL=createBottomSheetScrollableComponent.js.map