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 {
23
2
BottomSheetBackdrop ,
24
- BottomSheetBackgroundProps ,
25
3
BottomSheetBackdropProps ,
4
+ BottomSheetBackgroundProps ,
5
+ BottomSheetModal ,
6
+ BottomSheetView ,
26
7
} 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' ;
38
9
import { StyleSheet } from 'react-native' ;
39
10
import { useReducedMotion } from 'react-native-reanimated' ;
40
- import { useTheme } from 'styled-components/native' ;
41
11
42
12
import { __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';
47
20
import BottomSheetBackground from './BottomSheetBackground' ;
48
21
49
- export interface BottomSheetWrapperProps {
50
- children : ReactElement ;
51
- view : TViewController ;
22
+ type SheetProps = {
23
+ view : SheetId ;
52
24
snapPoints : number [ ] ;
53
- backdrop ?: boolean ;
25
+ children : ReactNode ;
54
26
testID ?: string ;
55
27
onOpen ?: ( ) => void ;
56
28
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 ) => {
162
50
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
+ />
183
57
) ;
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
+ } ;
186
105
187
106
const styles = StyleSheet . create ( {
188
107
container : {
@@ -198,4 +117,4 @@ const styles = StyleSheet.create({
198
117
} ,
199
118
} ) ;
200
119
201
- export default memo ( BottomSheetWrapper ) ;
120
+ export default Sheet ;
0 commit comments