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' ;
39- import { useReducedMotion } from 'react-native-reanimated' ;
40- import { useTheme } from 'styled-components/native' ;
41-
4210import { __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' ;
11+ import useColors from '../hooks/colors' ;
12+ // import { useAppDispatch } from '../hooks/redux';
13+ import {
14+ SheetId ,
15+ useSheetRef ,
16+ } from '../navigation/bottom-sheet/SheetRefsProvider' ;
17+ // import { closeSheet } from '../store/slices/ui';
4718import BottomSheetBackground from './BottomSheetBackground' ;
4819
49- export interface BottomSheetWrapperProps {
50- children : ReactElement ;
51- view : TViewController ;
20+ type SheetProps = {
21+ view : SheetId ;
5222 snapPoints : number [ ] ;
53- backdrop ?: boolean ;
23+ children : ReactNode ;
5424 testID ?: string ;
5525 onOpen ?: ( ) => void ;
5626 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-
27+ } ;
28+
29+ const Sheet = ( {
30+ view,
31+ snapPoints,
32+ children,
33+ testID,
34+ onOpen,
35+ onClose,
36+ } : SheetProps ) => {
37+ const colors = useColors ( ) ;
38+ const sheetRef = useSheetRef ( view ) ;
39+ // const dispatch = useAppDispatch();
40+ // const reducedMotion = useReducedMotion();
41+
42+ // https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936
43+ // do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it
44+ const activeOffsetX = useMemo ( ( ) => [ - 999 , 999 ] , [ ] ) ;
45+ const activeOffsetY = useMemo ( ( ) => [ - 10 , 10 ] , [ ] ) ;
46+
47+ const backdropComponent = useCallback ( ( props : BottomSheetBackdropProps ) => {
16248 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 >
49+ < BottomSheetBackdrop
50+ { ...props }
51+ disappearsOnIndex = { - 1 }
52+ appearsOnIndex = { 0 }
53+ accessibilityLabel = "Close"
54+ />
18355 ) ;
184- } ,
185- ) ;
56+ } , [ ] ) ;
57+
58+ const backgroundComponent = useCallback (
59+ ( { style } : BottomSheetBackgroundProps ) => (
60+ < BottomSheetBackground style = { style } />
61+ ) ,
62+ [ ] ,
63+ ) ;
64+
65+ const onChange = useCallback (
66+ ( index : number ) => {
67+ if ( index === - 1 ) {
68+ onClose ?.( ) ;
69+ // reset sheet params
70+ // dispatch(closeSheet(view));
71+ } else if ( index >= 0 ) {
72+ onOpen ?.( ) ;
73+ }
74+ } ,
75+ [ onOpen , onClose ] ,
76+ ) ;
77+
78+ return (
79+ < BottomSheetModal
80+ name = { view }
81+ ref = { sheetRef }
82+ snapPoints = { snapPoints }
83+ handleStyle = { styles . handle }
84+ handleIndicatorStyle = { { backgroundColor : colors . gray2 } }
85+ backdropComponent = { backdropComponent }
86+ backgroundComponent = { backgroundComponent }
87+ stackBehavior = "push"
88+ animateOnMount = { ! __E2E__ }
89+ enablePanDownToClose = { true }
90+ keyboardBlurBehavior = "restore"
91+ // enableDismissOnClose={false}
92+ // @ts -ignore
93+ activeOffsetX = { activeOffsetX }
94+ // @ts -ignore
95+ activeOffsetY = { activeOffsetY }
96+ onChange = { onChange } >
97+ < BottomSheetView style = { styles . container } testID = { testID } >
98+ { children }
99+ </ BottomSheetView >
100+ </ BottomSheetModal >
101+ ) ;
102+ } ;
186103
187104const styles = StyleSheet . create ( {
188105 container : {
@@ -198,4 +115,4 @@ const styles = StyleSheet.create({
198115 } ,
199116} ) ;
200117
201- export default memo ( BottomSheetWrapper ) ;
118+ export default Sheet ;
0 commit comments