@niibase/bottom-sheet-manager 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/lib/commonjs/events.js +35 -0
  4. package/lib/commonjs/events.js.map +1 -0
  5. package/lib/commonjs/index.js +85 -0
  6. package/lib/commonjs/index.js.map +1 -0
  7. package/lib/commonjs/manager.js +171 -0
  8. package/lib/commonjs/manager.js.map +1 -0
  9. package/lib/commonjs/provider.js +229 -0
  10. package/lib/commonjs/provider.js.map +1 -0
  11. package/lib/commonjs/router/index.js +100 -0
  12. package/lib/commonjs/router/index.js.map +1 -0
  13. package/lib/commonjs/router/router.js +72 -0
  14. package/lib/commonjs/router/router.js.map +1 -0
  15. package/lib/commonjs/router/types.js +6 -0
  16. package/lib/commonjs/router/types.js.map +1 -0
  17. package/lib/commonjs/router/view.js +180 -0
  18. package/lib/commonjs/router/view.js.map +1 -0
  19. package/lib/commonjs/sheet.js +240 -0
  20. package/lib/commonjs/sheet.js.map +1 -0
  21. package/lib/commonjs/types.js +6 -0
  22. package/lib/commonjs/types.js.map +1 -0
  23. package/lib/module/events.js +29 -0
  24. package/lib/module/events.js.map +1 -0
  25. package/lib/module/index.js +6 -0
  26. package/lib/module/index.js.map +1 -0
  27. package/lib/module/manager.js +165 -0
  28. package/lib/module/manager.js.map +1 -0
  29. package/lib/module/provider.js +210 -0
  30. package/lib/module/provider.js.map +1 -0
  31. package/lib/module/router/index.js +79 -0
  32. package/lib/module/router/index.js.map +1 -0
  33. package/lib/module/router/router.js +65 -0
  34. package/lib/module/router/router.js.map +1 -0
  35. package/lib/module/router/types.js +2 -0
  36. package/lib/module/router/types.js.map +1 -0
  37. package/lib/module/router/view.js +173 -0
  38. package/lib/module/router/view.js.map +1 -0
  39. package/lib/module/sheet.js +232 -0
  40. package/lib/module/sheet.js.map +1 -0
  41. package/lib/module/types.js +2 -0
  42. package/lib/module/types.js.map +1 -0
  43. package/lib/typescript/events.d.ts +16 -0
  44. package/lib/typescript/events.d.ts.map +1 -0
  45. package/lib/typescript/index.d.ts +6 -0
  46. package/lib/typescript/index.d.ts.map +1 -0
  47. package/lib/typescript/manager.d.ts +78 -0
  48. package/lib/typescript/manager.d.ts.map +1 -0
  49. package/lib/typescript/provider.d.ts +69 -0
  50. package/lib/typescript/provider.d.ts.map +1 -0
  51. package/lib/typescript/router/index.d.ts +59 -0
  52. package/lib/typescript/router/index.d.ts.map +1 -0
  53. package/lib/typescript/router/router.d.ts +47 -0
  54. package/lib/typescript/router/router.d.ts.map +1 -0
  55. package/lib/typescript/router/types.d.ts +46 -0
  56. package/lib/typescript/router/types.d.ts.map +1 -0
  57. package/lib/typescript/router/view.d.ts +11 -0
  58. package/lib/typescript/router/view.d.ts.map +1 -0
  59. package/lib/typescript/sheet.d.ts +19 -0
  60. package/lib/typescript/sheet.d.ts.map +1 -0
  61. package/lib/typescript/types.d.ts +125 -0
  62. package/lib/typescript/types.d.ts.map +1 -0
  63. package/package.json +102 -0
  64. package/src/events.ts +40 -0
  65. package/src/index.ts +11 -0
  66. package/src/manager.ts +223 -0
  67. package/src/provider.tsx +293 -0
  68. package/src/router/index.tsx +130 -0
  69. package/src/router/router.ts +94 -0
  70. package/src/router/types.ts +117 -0
  71. package/src/router/view.tsx +265 -0
  72. package/src/sheet.tsx +350 -0
  73. package/src/types.ts +153 -0
@@ -0,0 +1,265 @@
1
+ import {
2
+ BottomSheetBackdrop,
3
+ BottomSheetModal,
4
+ BottomSheetModalProps,
5
+ BottomSheetModalProvider,
6
+ } from "@gorhom/bottom-sheet";
7
+ import { ParamListBase, useTheme } from "@react-navigation/native";
8
+ import * as React from "react";
9
+ import { StatusBar } from "react-native";
10
+ import Animated, {
11
+ Easing,
12
+ interpolate,
13
+ interpolateColor,
14
+ runOnJS,
15
+ useAnimatedReaction,
16
+ useAnimatedStyle,
17
+ useSharedValue,
18
+ withSpring,
19
+ } from "react-native-reanimated";
20
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
21
+
22
+ import type {
23
+ BottomSheetDescriptorMap,
24
+ BottomSheetNavigationConfig,
25
+ BottomSheetNavigationHelpers,
26
+ BottomSheetNavigationProp,
27
+ BottomSheetNavigationState,
28
+ } from "./types";
29
+
30
+ type BottomSheetModalScreenProps = BottomSheetModalProps & {
31
+ navigation: BottomSheetNavigationProp<ParamListBase>;
32
+ /**
33
+ * When `true`, tapping on the backdrop will not dismiss the modal.
34
+ * @default false
35
+ */
36
+ clickThrough?: boolean;
37
+
38
+ /**
39
+ * Opacity of the sheet's overlay.
40
+ * @default 0.45
41
+ */
42
+ opacity?: number;
43
+
44
+ /**
45
+ * IOS modal sheet type of animation
46
+ * @default false
47
+ */
48
+ iosModalSheetTypeOfAnimation?: boolean;
49
+ };
50
+
51
+ function BottomSheetModalScreen({
52
+ index,
53
+ navigation,
54
+ clickThrough,
55
+ iosModalSheetTypeOfAnimation,
56
+ opacity,
57
+ children,
58
+ ...props
59
+ }: BottomSheetModalScreenProps) {
60
+ const ref = React.useRef<BottomSheetModal>(null);
61
+ const lastIndexRef = React.useRef(index);
62
+
63
+ // Present on mount.
64
+ React.useEffect(() => {
65
+ ref.current?.present();
66
+ }, []);
67
+
68
+ const isMounted = React.useRef(true);
69
+ React.useEffect(() => {
70
+ return () => {
71
+ isMounted.current = false;
72
+ };
73
+ }, []);
74
+
75
+ React.useEffect(() => {
76
+ if (index != null && lastIndexRef.current !== index) {
77
+ ref.current?.snapToIndex(index);
78
+ }
79
+ }, [index]);
80
+
81
+ const onChange = React.useCallback(
82
+ (newIndex: number) => {
83
+ const currentIndex = lastIndexRef.current;
84
+ lastIndexRef.current = newIndex;
85
+ if (newIndex >= 0 && newIndex !== currentIndex) {
86
+ navigation.snapTo(newIndex);
87
+ }
88
+ },
89
+ [navigation],
90
+ );
91
+
92
+ const onDismiss = React.useCallback(() => {
93
+ // BottomSheetModal will call onDismiss on unmount, be we do not want that since
94
+ // we already popped the screen.
95
+ if (isMounted.current) {
96
+ navigation.goBack();
97
+ }
98
+ }, [navigation]);
99
+
100
+ return (
101
+ <BottomSheetModal
102
+ ref={ref}
103
+ onDismiss={onDismiss}
104
+ onChange={onChange}
105
+ index={index}
106
+ backdropComponent={(props) => (
107
+ <BottomSheetBackdrop
108
+ {...props}
109
+ appearsOnIndex={0}
110
+ disappearsOnIndex={-1}
111
+ enableTouchThrough={!!clickThrough}
112
+ opacity={opacity || 0.45}
113
+ />
114
+ )}
115
+ {...props}
116
+ >
117
+ {children}
118
+ </BottomSheetModal>
119
+ );
120
+ }
121
+
122
+ const DEFAULT_SNAP_POINTS = ["66%"];
123
+
124
+ type Props = BottomSheetNavigationConfig & {
125
+ state: BottomSheetNavigationState<ParamListBase>;
126
+ navigation: BottomSheetNavigationHelpers;
127
+ descriptors: BottomSheetDescriptorMap;
128
+ };
129
+
130
+ export function BottomSheetView({ state, descriptors }: Props) {
131
+ const { colors } = useTheme();
132
+ const { top } = useSafeAreaInsets();
133
+ const themeBackgroundStyle = React.useMemo(
134
+ () => ({
135
+ backgroundColor: colors.card,
136
+ }),
137
+ [colors.card],
138
+ );
139
+ const themeHandleIndicatorStyle = React.useMemo(
140
+ () => ({
141
+ backgroundColor: colors.border,
142
+ height: 5,
143
+ width: 50,
144
+ }),
145
+ [colors.border],
146
+ );
147
+
148
+ // IOS modal sheet type of animation
149
+ const isFullScreen = useSharedValue(0);
150
+ const colorStyle = useAnimatedStyle(() => ({
151
+ flex: 1,
152
+ backgroundColor: interpolateColor(
153
+ isFullScreen.value,
154
+ [0, 1],
155
+ ["transparent", "#000"],
156
+ ),
157
+ }));
158
+ const animatedStyle = useAnimatedStyle(() => ({
159
+ flex: 1,
160
+ transform: [
161
+ {
162
+ scaleX: withSpring(interpolate(isFullScreen.value, [0, 1], [1, 0.92]), {
163
+ damping: 15,
164
+ stiffness: 100,
165
+ }),
166
+ },
167
+ {
168
+ translateY: withSpring(interpolate(isFullScreen.value, [0, 1], [0, top + 5]), {
169
+ damping: 15,
170
+ stiffness: 100,
171
+ }),
172
+ },
173
+ ],
174
+ }));
175
+
176
+ // Since background color is white, we need to set status bar to light
177
+ const setStatusBar = StatusBar.setBarStyle;
178
+ useAnimatedReaction(
179
+ () => isFullScreen.value,
180
+ (currentValue) => {
181
+ "worklet";
182
+ if (currentValue > -1) {
183
+ runOnJS(setStatusBar)(currentValue >= 0.5 ? "light-content" : "default");
184
+ }
185
+ },
186
+ [],
187
+ );
188
+
189
+ // Avoid rendering provider if we only have one screen.
190
+ const shouldRenderProvider = React.useRef(false);
191
+ shouldRenderProvider.current = shouldRenderProvider.current || state.routes.length > 1;
192
+
193
+ const firstRoute = state.routes[0];
194
+ if (!firstRoute) {
195
+ // no routes at all, probably shouldn't happen, but let's be defensive
196
+ return null;
197
+ }
198
+
199
+ const firstDescriptor = descriptors[firstRoute.key];
200
+ if (!firstDescriptor) {
201
+ // if we don't have a descriptor for the first route, bail out
202
+ return null;
203
+ }
204
+
205
+ return (
206
+ <>
207
+ <Animated.View style={colorStyle}>
208
+ <Animated.View style={animatedStyle}>{firstDescriptor.render?.()}</Animated.View>
209
+ </Animated.View>
210
+ {shouldRenderProvider.current && (
211
+ <BottomSheetModalProvider>
212
+ {state.routes.slice(1).map((route) => {
213
+ const descriptor = descriptors[route.key];
214
+ if (!descriptor) return null;
215
+
216
+ const { options, navigation, render } = descriptor;
217
+ const {
218
+ index,
219
+ snapPoints,
220
+ handleStyle,
221
+ backgroundStyle,
222
+ handleIndicatorStyle,
223
+ enableDynamicSizing,
224
+ ...sheetProps
225
+ } = options;
226
+
227
+ return (
228
+ <BottomSheetModalScreen
229
+ key={route.key}
230
+ // Make sure index is in range, it could be out if snapToIndex is persisted
231
+ // and snapPoints is changed.
232
+ index={Math.min(
233
+ route.snapToIndex ?? index ?? 0,
234
+ !!snapPoints ? snapPoints.length - 1 : 0,
235
+ )}
236
+ snapPoints={
237
+ !snapPoints && !enableDynamicSizing ? DEFAULT_SNAP_POINTS : snapPoints
238
+ }
239
+ onAnimate={(_, to) => {
240
+ // @ts-ignore TODO: Fix types
241
+ isFullScreen.value = ["%100", "100%"].includes(snapPoints?.[to])
242
+ ? 1
243
+ : 0;
244
+ }}
245
+ animationConfigs={{
246
+ duration: 300,
247
+ easing: Easing.bezier(0.25, 0.1, 0.25, 1),
248
+ }}
249
+ topInset={top + 18}
250
+ navigation={navigation}
251
+ enableDynamicSizing={enableDynamicSizing}
252
+ backgroundStyle={[themeBackgroundStyle, backgroundStyle]}
253
+ handleIndicatorStyle={[themeHandleIndicatorStyle, handleIndicatorStyle]}
254
+ handleStyle={[themeBackgroundStyle, { borderRadius: 20 }, handleStyle]}
255
+ {...sheetProps}
256
+ >
257
+ {render?.()}
258
+ </BottomSheetModalScreen>
259
+ );
260
+ })}
261
+ </BottomSheetModalProvider>
262
+ )}
263
+ </>
264
+ );
265
+ }
package/src/sheet.tsx ADDED
@@ -0,0 +1,350 @@
1
+ import RNBottomSheet, {
2
+ BottomSheetBackdrop,
3
+ BottomSheetFlatList,
4
+ BottomSheetFooter,
5
+ BottomSheetFooterContainer,
6
+ BottomSheetHandle,
7
+ BottomSheetModal,
8
+ BottomSheetScrollView,
9
+ BottomSheetSectionList,
10
+ BottomSheetTextInput,
11
+ BottomSheetView,
12
+ BottomSheetVirtualizedList,
13
+ } from "@gorhom/bottom-sheet";
14
+ import {
15
+ BackHandler,
16
+ Platform,
17
+ StyleSheet,
18
+ View,
19
+ type NativeEventSubscription,
20
+ } from "react-native";
21
+ import {
22
+ Easing,
23
+ interpolate,
24
+ useAnimatedReaction,
25
+ useSharedValue,
26
+ } from "react-native-reanimated";
27
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
28
+ import { useTheme } from "@react-navigation/native";
29
+ import React from "react";
30
+
31
+ import {
32
+ useProviderContext,
33
+ useSheetAnimationContext,
34
+ useSheetIDContext,
35
+ useSheetRef,
36
+ } from "./provider";
37
+ import { BottomSheetInstance, BottomSheetProps, SheetIds } from "./types";
38
+ import { PrivateManager } from "./manager";
39
+ import { eventManager } from "./events";
40
+
41
+ interface BottomSheetFC
42
+ extends React.MemoExoticComponent<React.ForwardRefExoticComponent<BottomSheetProps>> {
43
+ <Id extends SheetIds>(
44
+ props: BottomSheetProps & React.RefAttributes<BottomSheetInstance<Id>>,
45
+ ): React.JSX.Element;
46
+
47
+ // Components
48
+ View: typeof BottomSheetView;
49
+ ScrollView: typeof BottomSheetScrollView;
50
+ FlatList: typeof BottomSheetFlatList;
51
+ SectionList: typeof BottomSheetSectionList;
52
+ VirtualizedList: typeof BottomSheetVirtualizedList;
53
+ Handle: typeof BottomSheetHandle;
54
+ Footer: typeof BottomSheetFooter;
55
+ FooterContainer: typeof BottomSheetFooterContainer;
56
+ Backdrop: typeof BottomSheetBackdrop;
57
+ TextInput: typeof BottomSheetTextInput;
58
+ }
59
+
60
+ const useSheetManager = ({
61
+ id,
62
+ onHide,
63
+ onBeforeShow,
64
+ onContextUpdate,
65
+ }: {
66
+ id?: string;
67
+ onHide: (data?: any, dismiss?: boolean) => void;
68
+ onBeforeShow?: (data?: any) => void;
69
+ onContextUpdate: () => void;
70
+ }) => {
71
+ const [visible, setVisible] = React.useState(false);
72
+ const currentContext = useProviderContext();
73
+
74
+ React.useEffect(() => {
75
+ if (!id) return undefined;
76
+
77
+ const subscriptions = [
78
+ eventManager.subscribe(`show_${id}`, (data: any, context?: string) => {
79
+ if (currentContext !== context || visible) return;
80
+ onContextUpdate?.();
81
+ onBeforeShow?.(data);
82
+ setVisible(true);
83
+ }),
84
+ eventManager.subscribe(`hide_${id}`, (data: any, context, dismiss?: boolean) => {
85
+ if (currentContext !== context) return;
86
+ onHide?.(data, dismiss);
87
+ }),
88
+ ];
89
+ return () => {
90
+ subscriptions.forEach((s) => s?.unsubscribe?.());
91
+ };
92
+ }, [id, onHide, onBeforeShow, onContextUpdate, currentContext]);
93
+
94
+ return { visible, setVisible };
95
+ };
96
+
97
+ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetProps>(
98
+ (
99
+ {
100
+ children,
101
+ snapPoints,
102
+ onClose,
103
+ onBeforeShow,
104
+ stackBehavior = "switch",
105
+ hardwareBackPressToClose = true,
106
+ enableDynamicSizing = false,
107
+ handleIndicatorStyle,
108
+ iosModalSheetTypeOfAnimation: pageAnimation,
109
+ backgroundStyle,
110
+ handleStyle,
111
+ clickThrough,
112
+ fullScreen,
113
+ opacity,
114
+
115
+ ...props
116
+ },
117
+ ref,
118
+ ) => {
119
+ const currentSheetRef = useSheetRef();
120
+ const currentCtx = useProviderContext();
121
+
122
+ const { isFullScreen, iosModalSheetTypeOfAnimation } = useSheetAnimationContext();
123
+ const animatedIndex = useSharedValue(0);
124
+
125
+ const { colors } = useTheme();
126
+ const { top } = useSafeAreaInsets();
127
+ const themeBackgroundStyle = React.useMemo(
128
+ () => ({ backgroundColor: colors.card }),
129
+ [colors.card],
130
+ );
131
+ const themeHandleIndicatorStyle = React.useMemo(
132
+ () => ({
133
+ backgroundColor: colors.border,
134
+ height: 5,
135
+ width: 50,
136
+ }),
137
+ [colors.border],
138
+ );
139
+
140
+ const valueRef = React.useRef<unknown>(null);
141
+ const bottomSheetRef = React.useRef<BottomSheetModal>(null);
142
+ const hardwareBackPressEvent = React.useRef<NativeEventSubscription>(
143
+ null,
144
+ ) as React.MutableRefObject<NativeEventSubscription>;
145
+
146
+ const id = useSheetIDContext();
147
+ const sheetId = props.id || id;
148
+ useSheetManager({
149
+ id: sheetId,
150
+ onHide: (data, dismiss) => hideSheet(data, true, dismiss),
151
+ onBeforeShow: (data) => {
152
+ onBeforeShow?.(data);
153
+ valueRef.current = undefined;
154
+ currentSheetRef.current = getInstance();
155
+ },
156
+ onContextUpdate: () => {
157
+ if (sheetId) {
158
+ PrivateManager.add(sheetId, currentCtx);
159
+ PrivateManager.registerRef(sheetId, currentCtx, {
160
+ current: getInstance(),
161
+ } as React.RefObject<BottomSheetInstance>);
162
+ }
163
+ },
164
+ });
165
+
166
+ useAnimatedReaction(
167
+ () => {
168
+ if (!!iosModalSheetTypeOfAnimation || !!pageAnimation) {
169
+ isFullScreen.value = 0;
170
+ }
171
+ return animatedIndex.value;
172
+ },
173
+ (index) => {
174
+ "worklet";
175
+ const points: (string | number)[] = ["%100", "100%"];
176
+ const checkFullScreen = fullScreen
177
+ ? -1
178
+ : snapPoints instanceof Array
179
+ ? snapPoints.findIndex((p) => points.includes(p))
180
+ : snapPoints?.value?.findIndex((p) => points.includes(p)) || -1;
181
+
182
+ if (
183
+ -1 !== checkFullScreen &&
184
+ (!!iosModalSheetTypeOfAnimation || !!pageAnimation)
185
+ ) {
186
+ isFullScreen.value = interpolate(
187
+ index,
188
+ [checkFullScreen - 1, checkFullScreen],
189
+ [0, 1],
190
+ );
191
+ }
192
+ },
193
+ [snapPoints],
194
+ );
195
+
196
+ const hideSheet = React.useCallback(
197
+ (data?: any, isSheetManagerOrRef?: boolean, dismiss?: boolean) => {
198
+ const value = data ?? valueRef.current;
199
+
200
+ if (!dismiss || stackBehavior !== "push") {
201
+ hardwareBackPressEvent.current?.remove();
202
+ bottomSheetRef.current?.close();
203
+ onClose?.(value);
204
+ }
205
+
206
+ if (sheetId) {
207
+ PrivateManager.remove(sheetId, currentCtx);
208
+ if (dismiss && stackBehavior === "push") return;
209
+
210
+ const history = PrivateManager.history.length >= 1;
211
+ eventManager.publish(
212
+ `onclose_${sheetId}`,
213
+ value,
214
+ currentCtx,
215
+ history || dismiss,
216
+ );
217
+
218
+ if (stackBehavior === "replace") return;
219
+ if (dismiss) {
220
+ PrivateManager.history.push({ id: sheetId, context: currentCtx });
221
+ } else if (history) {
222
+ const { id, context } = PrivateManager.history.pop()!;
223
+ eventManager.publish(`show_wrap_${id}`, undefined, context, true);
224
+ }
225
+ }
226
+ if (isSheetManagerOrRef) valueRef.current = data;
227
+ },
228
+ [sheetId, currentCtx, onClose],
229
+ );
230
+ const getInstance = React.useCallback(
231
+ (): BottomSheetInstance => ({
232
+ close(options = {}): void {
233
+ valueRef.current = (options as Record<string, unknown>).value;
234
+ bottomSheetRef.current?.close(options?.animationConfigs);
235
+ },
236
+ expand(animationConfigs): void {
237
+ bottomSheetRef.current?.expand(animationConfigs);
238
+ },
239
+ collapse(animationConfigs): void {
240
+ bottomSheetRef.current?.collapse(animationConfigs);
241
+ },
242
+ snapToIndex(index: number, animationConfigs): void {
243
+ bottomSheetRef.current?.snapToIndex(index, animationConfigs);
244
+ },
245
+ snapToPosition(position, animationConfigs): void {
246
+ bottomSheetRef.current?.snapToPosition(position, animationConfigs);
247
+ },
248
+ }),
249
+ [],
250
+ );
251
+
252
+ React.useEffect(() => {
253
+ if (sheetId) {
254
+ PrivateManager.registerRef(sheetId, currentCtx, {
255
+ current: getInstance(),
256
+ } as React.RefObject<BottomSheetInstance>);
257
+ }
258
+ currentSheetRef.current = getInstance();
259
+ }, [currentCtx, getInstance, sheetId, currentSheetRef]);
260
+
261
+ React.useEffect(() => {
262
+ if (Platform.OS === "android" && hardwareBackPressToClose) {
263
+ hardwareBackPressEvent.current = BackHandler.addEventListener(
264
+ "hardwareBackPress",
265
+ () => {
266
+ bottomSheetRef.current?.close();
267
+ return true;
268
+ },
269
+ );
270
+ }
271
+
272
+ return () => hardwareBackPressEvent.current?.remove();
273
+ }, [hardwareBackPressToClose]);
274
+
275
+ React.useImperativeHandle(ref, getInstance, [getInstance]);
276
+
277
+ return (
278
+ <View
279
+ pointerEvents="box-none"
280
+ style={[
281
+ StyleSheet.absoluteFill,
282
+ {
283
+ zIndex:
284
+ sheetId && stackBehavior === "push"
285
+ ? PrivateManager.zIndex(sheetId, currentCtx)
286
+ : 0,
287
+ },
288
+ ]}
289
+ >
290
+ <RNBottomSheet
291
+ enableDynamicSizing={enableDynamicSizing}
292
+ animationConfigs={{ duration: 400, easing: Easing.bezier(0.25, 0.1, 0.25, 1) }}
293
+ backdropComponent={(props) => (
294
+ <BottomSheetBackdrop
295
+ enableTouchThrough={!!clickThrough}
296
+ opacity={opacity || 0.45}
297
+ disappearsOnIndex={-1}
298
+ appearsOnIndex={0}
299
+ {...props}
300
+ />
301
+ )}
302
+ {...props}
303
+ ref={bottomSheetRef}
304
+ onClose={hideSheet}
305
+ animatedIndex={animatedIndex}
306
+ topInset={
307
+ fullScreen
308
+ ? 0
309
+ : top + (iosModalSheetTypeOfAnimation || pageAnimation ? 20 : 5)
310
+ }
311
+ snapPoints={enableDynamicSizing ? undefined : (snapPoints ?? ["66%"])}
312
+ handleIndicatorStyle={[themeHandleIndicatorStyle, handleIndicatorStyle]}
313
+ backgroundStyle={[themeBackgroundStyle, backgroundStyle]}
314
+ handleStyle={[themeBackgroundStyle, handleStyle]}
315
+ >
316
+ {children}
317
+ </RNBottomSheet>
318
+ </View>
319
+ );
320
+ },
321
+ );
322
+
323
+ const BottomSheet = React.memo(BottomSheetComponent) as BottomSheetFC;
324
+ BottomSheet.displayName = "BottomSheet";
325
+
326
+ BottomSheet.View = BottomSheetView;
327
+ BottomSheet.ScrollView = BottomSheetScrollView;
328
+ BottomSheet.FlatList = BottomSheetFlatList;
329
+ BottomSheet.SectionList = BottomSheetSectionList;
330
+ BottomSheet.VirtualizedList = BottomSheetVirtualizedList;
331
+ BottomSheet.Handle = BottomSheetHandle;
332
+ BottomSheet.Footer = BottomSheetFooter;
333
+ BottomSheet.FooterContainer = BottomSheetFooterContainer;
334
+ BottomSheet.Backdrop = BottomSheetBackdrop;
335
+ BottomSheet.TextInput = BottomSheetTextInput;
336
+
337
+ try {
338
+ const { cssInterop } = require("nativewind");
339
+ cssInterop(BottomSheet, {
340
+ handleIndicatorClassName: "handleIndicatorStyle",
341
+ backgroundClassName: "backgroundStyle",
342
+ containerClassName: "containerStyle",
343
+ handleClassName: "handleStyle",
344
+ className: "style",
345
+ });
346
+ } catch (e) {
347
+ // Ignore error
348
+ }
349
+
350
+ export default BottomSheet;