1- /***********************************************************************************
2- * This component wraps the @gorhom/bottom-sheet library
3- * to more easily take advantage of it throughout the app.
4- *
5- * Implementation:
6- * const snapPoints = useSnapPoints('medium');
7- *
8- * <BottomSheetWrapper view="viewName" snapPoints={snapPoints}>
9- * <View>...</View>
10- * </BottomSheetWrapper>
11- *
12- * Usage Throughout App:
13- * dispatch(showBottomSheet('viewName'));
14- * dispatch(showBottomSheet('viewName', { option1: 'value' }));
15- * dispatch(closeSheet('viewName'));
16- *
17- * Check if a given view is open:
18- * getStore().user.viewController['viewName'].isOpen;
19- ***********************************************************************************/
20-
21- import BottomSheet , {
22- BottomSheetView ,
1+ import {
232 BottomSheetBackdrop ,
24- BottomSheetBackgroundProps ,
253 BottomSheetBackdropProps ,
4+ BottomSheetBackgroundProps ,
5+ BottomSheetModal ,
6+ BottomSheetView ,
267} from '@gorhom/bottom-sheet' ;
27- import React , {
28- memo ,
29- ReactElement ,
30- forwardRef ,
31- useImperativeHandle ,
32- useRef ,
33- useEffect ,
34- useCallback ,
35- useMemo ,
36- useState ,
37- } from 'react' ;
8+ import React , { ReactNode , useCallback , useMemo } from 'react' ;
389import { StyleSheet } from 'react-native' ;
3910import { useReducedMotion } from 'react-native-reanimated' ;
40- import { useTheme } from 'styled-components/native' ;
4111
4212import { __E2E__ } from '../constants/env' ;
43- import { useAppDispatch , useAppSelector } from '../hooks/redux' ;
44- import { viewControllerSelector } from '../store/reselect/ui' ;
45- import { closeSheet } from '../store/slices/ui' ;
46- import { TViewController } from '../store/types/ui' ;
13+ import useColors from '../hooks/colors' ;
14+ // import { useAppDispatch } from '../hooks/redux';
15+ import {
16+ SheetId ,
17+ useSheetRef ,
18+ } from '../navigation/bottom-sheet/SheetRefsProvider' ;
19+ // import { closeSheet } from '../store/slices/ui';
4720import BottomSheetBackground from './BottomSheetBackground' ;
4821
49- export interface BottomSheetWrapperProps {
50- children : ReactElement ;
51- view : TViewController ;
22+ type SheetProps = {
23+ view : SheetId ;
5224 snapPoints : number [ ] ;
53- backdrop ?: boolean ;
25+ children : ReactNode ;
5426 testID ?: string ;
5527 onOpen ?: ( ) => void ;
5628 onClose ?: ( ) => void ;
57- }
58-
59- const BottomSheetWrapper = forwardRef (
60- (
61- {
62- children,
63- view,
64- snapPoints,
65- backdrop = true ,
66- testID,
67- onOpen,
68- onClose,
69- } : BottomSheetWrapperProps ,
70- ref ,
71- ) : ReactElement => {
72- const bottomSheetRef = useRef < BottomSheet > ( null ) ;
73- const reducedMotion = useReducedMotion ( ) ;
74- const dispatch = useAppDispatch ( ) ;
75- const data = useAppSelector ( ( state ) => viewControllerSelector ( state , view ) ) ;
76- const theme = useTheme ( ) ;
77- const handleIndicatorStyle = useMemo (
78- ( ) => ( { backgroundColor : theme . colors . gray2 } ) ,
79- [ theme . colors . gray2 ] ,
80- ) ;
81- const [ mounted , setMounted ] = useState ( false ) ;
82-
83- // https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936
84- // do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it
85- const activeOffsetX = useMemo ( ( ) => [ - 999 , 999 ] , [ ] ) ;
86- const activeOffsetY = useMemo ( ( ) => [ - 10 , 10 ] , [ ] ) ;
87-
88- useEffect ( ( ) => {
89- if ( data . isOpen ) {
90- bottomSheetRef . current ?. snapToIndex ( 0 ) ;
91- } else {
92- bottomSheetRef . current ?. close ( ) ;
93- }
94- setTimeout ( ( ) => setMounted ( true ) , 500 ) ;
95- } , [ data . isOpen ] ) ;
96-
97- useImperativeHandle ( ref , ( ) => ( {
98- snapToIndex ( index = 0 ) : void {
99- bottomSheetRef . current ?. snapToIndex ( index ) ;
100- } ,
101- expand ( ) : void {
102- bottomSheetRef . current ?. snapToIndex ( 1 ) ;
103- } ,
104- close ( ) : void {
105- bottomSheetRef . current ?. close ( ) ;
106- } ,
107- } ) ) ;
108-
109- const _onOpen = useCallback ( ( ) => onOpen ?.( ) , [ onOpen ] ) ;
110-
111- const _onClose = useCallback ( ( ) => {
112- if ( data . isOpen ) {
113- dispatch ( closeSheet ( view ) ) ;
114- }
115- onClose ?.( ) ;
116- } , [ data . isOpen , view , onClose , dispatch ] ) ;
117-
118- // callbacks
119- const handleSheetChanges = useCallback (
120- ( index : number ) => {
121- if ( index === - 1 ) {
122- _onClose ( ) ;
123- } else if ( index >= 0 ) {
124- _onOpen ( ) ;
125- }
126- } ,
127- [ _onClose , _onOpen ] ,
128- ) ;
129-
130- const renderBackdrop = useCallback (
131- ( props : BottomSheetBackdropProps ) => {
132- if ( ! backdrop ) {
133- return null ;
134- }
135- return (
136- < BottomSheetBackdrop
137- { ...props }
138- disappearsOnIndex = { - 1 }
139- appearsOnIndex = { 0 }
140- accessibilityLabel = "Close"
141- />
142- ) ;
143- } ,
144- [ backdrop ] ,
145- ) ;
146-
147- const backgroundComponent = useCallback (
148- ( { style } : BottomSheetBackgroundProps ) => (
149- < BottomSheetBackground style = { style } />
150- ) ,
151- [ ] ,
152- ) ;
153-
154- const style = useMemo (
155- ( ) => [ styles . container , ! mounted && { minHeight : snapPoints [ 0 ] - 30 } ] ,
156- [ snapPoints , mounted ] ,
157- ) ;
158-
159- // Determine initial snapPoint index based on provided data.
160- const index = useMemo ( ( ) : number => ( data . isOpen ? 0 : - 1 ) , [ data . isOpen ] ) ;
161-
29+ } ;
30+
31+ const Sheet = ( {
32+ view,
33+ snapPoints,
34+ children,
35+ testID,
36+ onOpen,
37+ onClose,
38+ } : SheetProps ) => {
39+ const colors = useColors ( ) ;
40+ const sheetRef = useSheetRef ( view ) ;
41+ const isReducedMotion = useReducedMotion ( ) ;
42+ // const dispatch = useAppDispatch();
43+
44+ // https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936
45+ // do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it
46+ const activeOffsetX = useMemo ( ( ) => [ - 999 , 999 ] , [ ] ) ;
47+ const activeOffsetY = useMemo ( ( ) => [ - 10 , 10 ] , [ ] ) ;
48+
49+ const backdropComponent = useCallback ( ( props : BottomSheetBackdropProps ) => {
16250 return (
163- < BottomSheet
164- ref = { bottomSheetRef }
165- backgroundComponent = { backgroundComponent }
166- backdropComponent = { renderBackdrop }
167- handleIndicatorStyle = { handleIndicatorStyle }
168- handleStyle = { styles . handle }
169- index = { index }
170- snapPoints = { snapPoints }
171- animateOnMount = { ! reducedMotion && ! __E2E__ }
172- enablePanDownToClose = { true }
173- keyboardBlurBehavior = "restore"
174- // @ts -ignore
175- activeOffsetX = { activeOffsetX }
176- // @ts -ignore
177- activeOffsetY = { activeOffsetY }
178- onChange = { handleSheetChanges } >
179- < BottomSheetView style = { style } testID = { testID } >
180- { children }
181- </ BottomSheetView >
182- </ BottomSheet >
51+ < BottomSheetBackdrop
52+ { ...props }
53+ disappearsOnIndex = { - 1 }
54+ appearsOnIndex = { 0 }
55+ accessibilityLabel = "Close"
56+ />
18357 ) ;
184- } ,
185- ) ;
58+ } , [ ] ) ;
59+
60+ const backgroundComponent = useCallback (
61+ ( { style } : BottomSheetBackgroundProps ) => (
62+ < BottomSheetBackground style = { style } />
63+ ) ,
64+ [ ] ,
65+ ) ;
66+
67+ const onChange = useCallback (
68+ ( index : number ) => {
69+ if ( index === - 1 ) {
70+ onClose ?.( ) ;
71+ // reset sheet params
72+ // dispatch(closeSheet(view));
73+ } else if ( index >= 0 ) {
74+ onOpen ?.( ) ;
75+ }
76+ } ,
77+ [ onOpen , onClose ] ,
78+ ) ;
79+
80+ return (
81+ < BottomSheetModal
82+ name = { view }
83+ ref = { sheetRef }
84+ snapPoints = { snapPoints }
85+ handleStyle = { styles . handle }
86+ handleIndicatorStyle = { { backgroundColor : colors . gray2 } }
87+ backdropComponent = { backdropComponent }
88+ backgroundComponent = { backgroundComponent }
89+ stackBehavior = "push"
90+ animateOnMount = { ! isReducedMotion && ! __E2E__ }
91+ enablePanDownToClose = { true }
92+ keyboardBlurBehavior = "restore"
93+ // enableDismissOnClose={false}
94+ // @ts -ignore
95+ activeOffsetX = { activeOffsetX }
96+ // @ts -ignore
97+ activeOffsetY = { activeOffsetY }
98+ onChange = { onChange } >
99+ < BottomSheetView style = { styles . container } testID = { testID } >
100+ { children }
101+ </ BottomSheetView >
102+ </ BottomSheetModal >
103+ ) ;
104+ } ;
186105
187106const styles = StyleSheet . create ( {
188107 container : {
@@ -198,4 +117,4 @@ const styles = StyleSheet.create({
198117 } ,
199118} ) ;
200119
201- export default memo ( BottomSheetWrapper ) ;
120+ export default Sheet ;
0 commit comments