Open shav95 opened 5 months ago
Here is my custom modal, I cannot scroll inside this modal
import { Dispatch, FC, ReactNode, SetStateAction, useCallback, useContext, } from 'react'; import { Platform, Pressable, Modal as ReactNativeModal, ModalProps as ReactNativeModalProps, StyleProp, View, ViewStyle, } from 'react-native'; import Animated, { FadeIn, FadeOut, runOnJS, useAnimatedStyle, useSharedValue, } from 'react-native-reanimated';
import {CardWrapper, Icon, Loader} from 'molecules'; import { GestureHandlerRootView, GestureDetector, Gesture, } from 'react-native-gesture-handler'; import {useSelector} from 'react-redux'; import {getMainLoadingState, getPinState} from 'rtk'; import {IColor, ThemeContext} from 'theme'; import {modalStyles} from './modal-styles';
export interface ModalProps extends ReactNativeModalProps { children: ReactNode | ReactNode[]; showLoader?: boolean; isVisible: boolean; setIsVisible: Dispatch<SetStateAction>; swipeToClose?: boolean; showCloseButton?: boolean; showGrabber?: boolean; backgroundColor?: IColor; type?: 'modal' | 'bottom-sheet'; contentContainerStyles?: StyleProp; activateAfterLongPress?: number; }
const Modal: FC = ({ isVisible, setIsVisible, children, showLoader = false, swipeToClose = true, showCloseButton = false, showGrabber = true, backgroundColor = 'surface_overlay', type = 'modal', contentContainerStyles = {}, activateAfterLongPress = 180, ...props }) => { const {color} = useContext(ThemeContext); const isLoading = useSelector(getMainLoadingState);
// In Ios We Cannot Open Multiple Modals // Our Pin Menu Is Inside A Modal And When We Open Pin Modal Over Another Opened Modal, It Will Not Work On IOS const isPinVisible = useSelector(getPinState);
const translateY = useSharedValue(0);
const onClose = useCallback(() => { translateY.value = 0; setIsVisible(false); }, [translateY.value]);
const panGesture = Gesture.Pan() .onBegin(() => { translateY.value = 0; }) .onUpdate(event => { if (event.translationY > 0 && swipeToClose) translateY.value = event.translationY; }) .onEnd(event => { if (event.translationY > 100) { if (onClose && swipeToClose) { runOnJS(onClose)(); } } else { translateY.value = 0; } });
const simultaneousGesture = Gesture.Simultaneous( panGesture, Gesture.Native().disallowInterruption(false).shouldActivateOnStart(false), );
const animatedStyle = useAnimatedStyle(() => { return { transform: [ { translateY: translateY.value, }, ], }; });
return ( <ReactNativeModal {...props} animationType="fade" presentationStyle="overFullScreen" visible={Platform.OS === 'ios' ? !isPinVisible && isVisible : isVisible} transparent> <Animated.View entering={FadeIn} exiting={FadeOut} style={modalStyles({color, ...props}).animatedBackground}>
</Animated.View> <Loader isLoading={showLoader && isLoading} /> </ReactNativeModal>
); };
export default Modal;
@wonday
Here is my custom modal, I cannot scroll inside this modal
import { Dispatch, FC, ReactNode, SetStateAction, useCallback, useContext, } from 'react'; import { Platform, Pressable, Modal as ReactNativeModal, ModalProps as ReactNativeModalProps, StyleProp, View, ViewStyle, } from 'react-native'; import Animated, { FadeIn, FadeOut, runOnJS, useAnimatedStyle, useSharedValue, } from 'react-native-reanimated';
import {CardWrapper, Icon, Loader} from 'molecules'; import { GestureHandlerRootView, GestureDetector, Gesture, } from 'react-native-gesture-handler'; import {useSelector} from 'react-redux'; import {getMainLoadingState, getPinState} from 'rtk'; import {IColor, ThemeContext} from 'theme'; import {modalStyles} from './modal-styles';
export interface ModalProps extends ReactNativeModalProps { children: ReactNode | ReactNode[]; showLoader?: boolean; isVisible: boolean; setIsVisible: Dispatch<SetStateAction>;
swipeToClose?: boolean;
showCloseButton?: boolean;
showGrabber?: boolean;
backgroundColor?: IColor;
type?: 'modal' | 'bottom-sheet';
contentContainerStyles?: StyleProp;
activateAfterLongPress?: number;
}
const Modal: FC = ({
isVisible,
setIsVisible,
children,
showLoader = false,
swipeToClose = true,
showCloseButton = false,
showGrabber = true,
backgroundColor = 'surface_overlay',
type = 'modal',
contentContainerStyles = {},
activateAfterLongPress = 180,
...props
}) => {
const {color} = useContext(ThemeContext);
const isLoading = useSelector(getMainLoadingState);
// In Ios We Cannot Open Multiple Modals // Our Pin Menu Is Inside A Modal And When We Open Pin Modal Over Another Opened Modal, It Will Not Work On IOS const isPinVisible = useSelector(getPinState);
const translateY = useSharedValue(0);
const onClose = useCallback(() => { translateY.value = 0; setIsVisible(false); }, [translateY.value]);
const panGesture = Gesture.Pan() .onBegin(() => { translateY.value = 0; }) .onUpdate(event => { if (event.translationY > 0 && swipeToClose) translateY.value = event.translationY; }) .onEnd(event => { if (event.translationY > 100) { if (onClose && swipeToClose) { runOnJS(onClose)(); } } else { translateY.value = 0; } });
const simultaneousGesture = Gesture.Simultaneous( panGesture, Gesture.Native().disallowInterruption(false).shouldActivateOnStart(false), );
const animatedStyle = useAnimatedStyle(() => { return { transform: [ { translateY: translateY.value, }, ], }; });
return ( <ReactNativeModal {...props} animationType="fade" presentationStyle="overFullScreen" visible={Platform.OS === 'ios' ? !isPinVisible && isVisible : isVisible} transparent> <Animated.View entering={FadeIn} exiting={FadeOut} style={modalStyles({color, ...props}).animatedBackground}>
); };
export default Modal;