Created
August 11, 2023 20:30
-
-
Save juanchoperezj/0e42afa9850845101c3ec62847a92cd2 to your computer and use it in GitHub Desktop.
Alert component using react-native-bottom-sheet and event emmitter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { EventEmitter } from 'eventemitter3'; | |
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; | |
import { Text, View } from 'react-native'; | |
import { BottomSheetModal, BottomSheetModalProvider } from '@gorhom/bottom-sheet'; | |
import { useNavigation } from '@react-navigation/native'; | |
import { AuthStackScreens } from 'navigation/stacks/auth'; | |
import Button from 'common/Button'; | |
import styles from './styles'; | |
import { AlertEvents, AlertProps } from './types'; | |
const eventEmitter = new EventEmitter(); | |
const DURATION = 3000; | |
// this will mount in App.tsx and will be available everywhere | |
const alertListener = (callback: (props: AlertProps) => void) => { | |
eventEmitter.on(AlertEvents.DISPLAY_ALERT, (props: AlertProps) => { | |
callback(props); | |
}); | |
}; | |
const Alert = () => { | |
const [alertProps, setAlertProps] = useState<null | AlertProps>(null); | |
const timeoutRef = useRef<NodeJS.Timeout | null>(null); | |
const { navigate } = useNavigation(); | |
const bottomSheetModalRef = useRef<BottomSheetModal>(null); | |
// const snapPoints = useMemo(() => ['20%', '13%'], []); | |
const snapPoints = useMemo(() => ['20%', '20%'], []); | |
useEffect(() => { | |
alertListener((props: AlertProps) => { | |
console.log(props); | |
setAlertProps(props); | |
bottomSheetModalRef.current?.present({ | |
props, | |
}); | |
if (timeoutRef.current) { | |
clearTimeout(timeoutRef.current); | |
} | |
if (alertProps?.autoDismiss || alertProps?.duration) { | |
console.log('timeout'); | |
timeoutRef.current = setTimeout(() => { | |
bottomSheetModalRef.current?.close(); | |
}, alertProps?.duration ?? DURATION); | |
} | |
}); | |
return () => { | |
eventEmitter.removeAllListeners(); | |
if (timeoutRef.current) { | |
clearTimeout(timeoutRef.current); | |
} | |
}; | |
}, [alertProps?.autoDismiss, alertProps?.duration]); | |
return ( | |
<BottomSheetModalProvider> | |
<BottomSheetModal | |
overDragResistanceFactor={0} | |
ref={bottomSheetModalRef} | |
index={1} | |
bottomInset={46} | |
detached={true} | |
snapPoints={snapPoints} | |
backgroundStyle={styles.sheetBackground} | |
containerStyle={styles.sheetContainer} | |
style={styles.sheet}> | |
<View style={styles.contentContainer}> | |
<View> | |
<Text style={styles.title}>{alertProps?.title}</Text> | |
<Text style={styles.description}>{alertProps?.message}</Text> | |
</View> | |
<View style={styles.actionContainer}> | |
<Button | |
style={styles.button} | |
title="Add funds" | |
onPress={() => { | |
bottomSheetModalRef.current?.dismiss(); | |
navigate(AuthStackScreens.SignIn); | |
}} | |
/> | |
<Button | |
style={styles.button} | |
title="Close" | |
onPress={() => bottomSheetModalRef.current?.close()} | |
/> | |
</View> | |
</View> | |
</BottomSheetModal> | |
</BottomSheetModalProvider> | |
); | |
}; | |
export default Alert; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Alert from 'components/Alert'; | |
const App = () => { | |
return ( | |
<GestureHandlerRootView style={{ flex: 1 }}> | |
<NavigationContainer> | |
<Navigation /> | |
<Alert /> | |
</NavigationContainer> | |
</GestureHandlerRootView> | |
); | |
}; | |
// example of use anywhere in your app | |
const { showAlert } = useAlert(); | |
showAlert({ | |
title: "❌ You don't have enough money", | |
message: 'Please add more funds to your account to complete the transaction.', | |
autoDismiss: false, | |
}) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const useAlert = () => { | |
// const { dismiss } = useBottomSheetModal(); | |
const showAlert = useCallback((props: AlertProps) => { | |
eventEmitter.emit(AlertEvents.DISPLAY_ALERT, props); | |
}, []); | |
return { | |
showAlert, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment