react-native-bottom-sheet-stack 1.7.5 → 1.8.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 (108) hide show
  1. package/lib/commonjs/BottomSheetManaged.js +5 -172
  2. package/lib/commonjs/BottomSheetManaged.js.map +1 -1
  3. package/lib/commonjs/BottomSheetPersistent.js.map +1 -1
  4. package/lib/commonjs/BottomSheetRef.context.js.map +1 -1
  5. package/lib/commonjs/QueueItem.js +2 -2
  6. package/lib/commonjs/QueueItem.js.map +1 -1
  7. package/lib/commonjs/adapter.types.js +6 -0
  8. package/lib/commonjs/adapter.types.js.map +1 -0
  9. package/lib/commonjs/adapters/actions-sheet/ActionsSheetAdapter.js +137 -0
  10. package/lib/commonjs/adapters/actions-sheet/ActionsSheetAdapter.js.map +1 -0
  11. package/lib/commonjs/adapters/actions-sheet/index.js +13 -0
  12. package/lib/commonjs/adapters/actions-sheet/index.js.map +1 -0
  13. package/lib/commonjs/adapters/custom-modal/CustomModalAdapter.js +157 -0
  14. package/lib/commonjs/adapters/custom-modal/CustomModalAdapter.js.map +1 -0
  15. package/lib/commonjs/adapters/custom-modal/index.js +19 -0
  16. package/lib/commonjs/adapters/custom-modal/index.js.map +1 -0
  17. package/lib/commonjs/adapters/gorhom-sheet/GorhomSheetAdapter.js +187 -0
  18. package/lib/commonjs/adapters/gorhom-sheet/GorhomSheetAdapter.js.map +1 -0
  19. package/lib/commonjs/adapters/gorhom-sheet/index.js +13 -0
  20. package/lib/commonjs/adapters/gorhom-sheet/index.js.map +1 -0
  21. package/lib/commonjs/adapters/index.js +40 -0
  22. package/lib/commonjs/adapters/index.js.map +1 -0
  23. package/lib/commonjs/adapters/react-native-modal/ReactNativeModalAdapter.js +119 -0
  24. package/lib/commonjs/adapters/react-native-modal/ReactNativeModalAdapter.js.map +1 -0
  25. package/lib/commonjs/adapters/react-native-modal/index.js +13 -0
  26. package/lib/commonjs/adapters/react-native-modal/index.js.map +1 -0
  27. package/lib/commonjs/animatedRegistry.js +11 -1
  28. package/lib/commonjs/animatedRegistry.js.map +1 -1
  29. package/lib/commonjs/bottomSheetCoordinator.js +29 -22
  30. package/lib/commonjs/bottomSheetCoordinator.js.map +1 -1
  31. package/lib/commonjs/index.js +68 -1
  32. package/lib/commonjs/index.js.map +1 -1
  33. package/lib/commonjs/refsMap.js.map +1 -1
  34. package/lib/commonjs/useAdapterRef.js +29 -0
  35. package/lib/commonjs/useAdapterRef.js.map +1 -0
  36. package/lib/commonjs/useAnimatedIndex.js +47 -0
  37. package/lib/commonjs/useAnimatedIndex.js.map +1 -0
  38. package/lib/commonjs/useBottomSheetControl.js.map +1 -1
  39. package/lib/commonjs/useBottomSheetManager.js.map +1 -1
  40. package/lib/typescript/example/src/screens/HomeScreen.d.ts.map +1 -1
  41. package/lib/typescript/example/src/sheets/ContextSheets.d.ts.map +1 -1
  42. package/lib/typescript/example/src/sheets/ModalSheets.d.ts +8 -0
  43. package/lib/typescript/example/src/sheets/ModalSheets.d.ts.map +1 -0
  44. package/lib/typescript/example/src/sheets/ThirdPartyAdapterSheets.d.ts +17 -0
  45. package/lib/typescript/example/src/sheets/ThirdPartyAdapterSheets.d.ts.map +1 -0
  46. package/lib/typescript/example/src/sheets/index.d.ts +2 -0
  47. package/lib/typescript/example/src/sheets/index.d.ts.map +1 -1
  48. package/lib/typescript/src/BottomSheetManaged.d.ts +10 -9
  49. package/lib/typescript/src/BottomSheetManaged.d.ts.map +1 -1
  50. package/lib/typescript/src/BottomSheetPersistent.d.ts.map +1 -1
  51. package/lib/typescript/src/BottomSheetRef.context.d.ts +1 -4
  52. package/lib/typescript/src/BottomSheetRef.context.d.ts.map +1 -1
  53. package/lib/typescript/src/QueueItem.d.ts.map +1 -1
  54. package/lib/typescript/src/adapter.types.d.ts +33 -0
  55. package/lib/typescript/src/adapter.types.d.ts.map +1 -0
  56. package/lib/typescript/src/adapters/actions-sheet/ActionsSheetAdapter.d.ts +23 -0
  57. package/lib/typescript/src/adapters/actions-sheet/ActionsSheetAdapter.d.ts.map +1 -0
  58. package/lib/typescript/src/adapters/actions-sheet/index.d.ts +2 -0
  59. package/lib/typescript/src/adapters/actions-sheet/index.d.ts.map +1 -0
  60. package/lib/typescript/src/adapters/custom-modal/CustomModalAdapter.d.ts +9 -0
  61. package/lib/typescript/src/adapters/custom-modal/CustomModalAdapter.d.ts.map +1 -0
  62. package/lib/typescript/src/adapters/custom-modal/index.d.ts +4 -0
  63. package/lib/typescript/src/adapters/custom-modal/index.d.ts.map +1 -0
  64. package/lib/typescript/src/adapters/gorhom-sheet/GorhomSheetAdapter.d.ts +7 -0
  65. package/lib/typescript/src/adapters/gorhom-sheet/GorhomSheetAdapter.d.ts.map +1 -0
  66. package/lib/typescript/src/adapters/gorhom-sheet/index.d.ts +2 -0
  67. package/lib/typescript/src/adapters/gorhom-sheet/index.d.ts.map +1 -0
  68. package/lib/typescript/src/adapters/index.d.ts +5 -0
  69. package/lib/typescript/src/adapters/index.d.ts.map +1 -0
  70. package/lib/typescript/src/adapters/react-native-modal/ReactNativeModalAdapter.d.ts +22 -0
  71. package/lib/typescript/src/adapters/react-native-modal/ReactNativeModalAdapter.d.ts.map +1 -0
  72. package/lib/typescript/src/adapters/react-native-modal/index.d.ts +2 -0
  73. package/lib/typescript/src/adapters/react-native-modal/index.d.ts.map +1 -0
  74. package/lib/typescript/src/animatedRegistry.d.ts +4 -0
  75. package/lib/typescript/src/animatedRegistry.d.ts.map +1 -1
  76. package/lib/typescript/src/bottomSheetCoordinator.d.ts +13 -7
  77. package/lib/typescript/src/bottomSheetCoordinator.d.ts.map +1 -1
  78. package/lib/typescript/src/index.d.ts +11 -0
  79. package/lib/typescript/src/index.d.ts.map +1 -1
  80. package/lib/typescript/src/refsMap.d.ts +1 -4
  81. package/lib/typescript/src/refsMap.d.ts.map +1 -1
  82. package/lib/typescript/src/useAdapterRef.d.ts +21 -0
  83. package/lib/typescript/src/useAdapterRef.d.ts.map +1 -0
  84. package/lib/typescript/src/useAnimatedIndex.d.ts +25 -0
  85. package/lib/typescript/src/useAnimatedIndex.d.ts.map +1 -0
  86. package/package.json +33 -2
  87. package/src/BottomSheetManaged.tsx +14 -106
  88. package/src/BottomSheetPersistent.tsx +2 -2
  89. package/src/BottomSheetRef.context.ts +2 -4
  90. package/src/QueueItem.tsx +4 -2
  91. package/src/adapter.types.ts +35 -0
  92. package/src/adapters/actions-sheet/ActionsSheetAdapter.tsx +83 -0
  93. package/src/adapters/actions-sheet/index.ts +4 -0
  94. package/src/adapters/custom-modal/CustomModalAdapter.tsx +131 -0
  95. package/src/adapters/custom-modal/index.ts +7 -0
  96. package/src/adapters/gorhom-sheet/GorhomSheetAdapter.tsx +118 -0
  97. package/src/adapters/gorhom-sheet/index.ts +4 -0
  98. package/src/adapters/index.ts +17 -0
  99. package/src/adapters/react-native-modal/ReactNativeModalAdapter.tsx +81 -0
  100. package/src/adapters/react-native-modal/index.ts +4 -0
  101. package/src/animatedRegistry.ts +10 -1
  102. package/src/bottomSheetCoordinator.ts +32 -24
  103. package/src/index.tsx +33 -0
  104. package/src/refsMap.ts +1 -4
  105. package/src/useAdapterRef.ts +28 -0
  106. package/src/useAnimatedIndex.ts +31 -0
  107. package/src/useBottomSheetControl.ts +2 -2
  108. package/src/useBottomSheetManager.tsx +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-bottom-sheet-stack",
3
- "version": "1.7.5",
3
+ "version": "1.8.0",
4
4
  "description": "Bottom Sheet Stack Manager",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "lib/commonjs/index.js",
@@ -73,12 +73,29 @@
73
73
  "@gorhom/bottom-sheet": ">=5.0.0",
74
74
  "react": "*",
75
75
  "react-native": "*",
76
+ "react-native-actions-sheet": ">=0.9.0",
76
77
  "react-native-gesture-handler": ">=2.0.0",
78
+ "react-native-modal": ">=11.0.0",
77
79
  "react-native-reanimated": ">=3.0.0",
78
80
  "react-native-safe-area-context": ">=5.0.0",
79
81
  "react-native-teleport": ">=0.5.0",
82
+ "react-native-worklets": ">=0.7.0",
80
83
  "zustand": ">=5.0.0"
81
84
  },
85
+ "peerDependenciesMeta": {
86
+ "@gorhom/bottom-sheet": {
87
+ "optional": true
88
+ },
89
+ "react-native-actions-sheet": {
90
+ "optional": true
91
+ },
92
+ "react-native-gesture-handler": {
93
+ "optional": true
94
+ },
95
+ "react-native-modal": {
96
+ "optional": true
97
+ }
98
+ },
82
99
  "workspaces": [
83
100
  "example"
84
101
  ],
@@ -109,7 +126,21 @@
109
126
  "plugins": {
110
127
  "@release-it/conventional-changelog": {
111
128
  "preset": {
112
- "name": "angular"
129
+ "name": "conventionalcommits",
130
+ "types": [
131
+ {
132
+ "type": "feat",
133
+ "section": "Features"
134
+ },
135
+ {
136
+ "type": "fix",
137
+ "section": "Bug Fixes"
138
+ },
139
+ {
140
+ "type": "perf",
141
+ "section": "Performance"
142
+ }
143
+ ]
113
144
  }
114
145
  }
115
146
  }
@@ -1,106 +1,14 @@
1
- import BottomSheetOriginal, {
2
- useBottomSheetSpringConfigs,
3
- type BottomSheetProps,
4
- } from '@gorhom/bottom-sheet';
5
- import { type BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
6
- import React from 'react';
7
-
8
- import { useAnimatedReaction } from 'react-native-reanimated';
9
- import { getAnimatedIndex } from './animatedRegistry';
10
- import { createSheetEventHandlers } from './bottomSheetCoordinator';
11
- import { useBottomSheetDefaultIndex } from './BottomSheetDefaultIndex.context';
12
- import { useBottomSheetRefContext } from './BottomSheetRef.context';
13
- import { useBottomSheetContext } from './useBottomSheetContext';
14
-
15
- export interface BottomSheetRef extends BottomSheetMethods {}
16
-
17
- interface BottomSheetManagedProps extends BottomSheetProps {}
18
-
19
- const nullBackdrop = () => null;
20
-
21
- export const BottomSheetManaged = React.forwardRef<
22
- BottomSheetRef,
23
- BottomSheetManagedProps
24
- >(
25
- (
26
- {
27
- children,
28
- onAnimate,
29
- onChange,
30
- onClose,
31
- enablePanDownToClose = true,
32
- backdropComponent = nullBackdrop,
33
- animatedIndex: externalAnimatedIndex,
34
- ...props
35
- },
36
- forwardedRef
37
- ) => {
38
- const { id } = useBottomSheetContext();
39
- const contextRef = useBottomSheetRefContext();
40
- const ref = contextRef ?? forwardedRef;
41
-
42
- const defaultIndex = useBottomSheetDefaultIndex();
43
- const contextAnimatedIndex = getAnimatedIndex(id);
44
-
45
- if (!contextAnimatedIndex) {
46
- throw new Error('animatedIndex must be defined in BottomSheetManaged');
47
- }
48
-
49
- useAnimatedReaction(
50
- () => contextAnimatedIndex.value,
51
- (value) => {
52
- externalAnimatedIndex?.set(value);
53
- }
54
- );
55
-
56
- const { handleAnimate, handleChange, handleClose } =
57
- createSheetEventHandlers(id);
58
-
59
- const wrappedOnAnimate: BottomSheetProps['onAnimate'] = (
60
- fromIndex,
61
- toIndex,
62
- fromPosition,
63
- toPosition
64
- ) => {
65
- handleAnimate(fromIndex, toIndex);
66
- onAnimate?.(fromIndex, toIndex, fromPosition, toPosition);
67
- };
68
-
69
- const wrappedOnChange: BottomSheetProps['onChange'] = (
70
- index,
71
- position,
72
- type
73
- ) => {
74
- handleChange(index);
75
- onChange?.(index, position, type);
76
- };
77
-
78
- const wrappedOnClose = () => {
79
- onClose?.();
80
- handleClose();
81
- };
82
-
83
- const config = useBottomSheetSpringConfigs({
84
- stiffness: 400,
85
- damping: 80,
86
- mass: 0.7,
87
- });
88
-
89
- return (
90
- <BottomSheetOriginal
91
- animationConfigs={config}
92
- ref={ref}
93
- {...props}
94
- index={defaultIndex}
95
- animatedIndex={contextAnimatedIndex}
96
- onChange={wrappedOnChange}
97
- onClose={wrappedOnClose}
98
- onAnimate={wrappedOnAnimate}
99
- backdropComponent={backdropComponent}
100
- enablePanDownToClose={enablePanDownToClose}
101
- >
102
- {children}
103
- </BottomSheetOriginal>
104
- );
105
- }
106
- );
1
+ /**
2
+ * Backward-compatible re-export of GorhomSheetAdapter.
3
+ *
4
+ * Existing users can continue importing `BottomSheetManaged` and `BottomSheetRef`
5
+ * without any changes. For new code, prefer importing `GorhomSheetAdapter` directly
6
+ * from 'react-native-bottom-sheet-stack/adapters/gorhom' or use the `ModalAdapter`
7
+ * for modal-based sheets.
8
+ */
9
+ export {
10
+ GorhomSheetAdapter as BottomSheetManaged,
11
+ type GorhomSheetAdapterProps as BottomSheetManagedProps,
12
+ } from './adapters/gorhom-sheet';
13
+
14
+ export type { SheetAdapterRef as BottomSheetRef } from './adapter.types';
@@ -1,5 +1,5 @@
1
- import type { BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
2
1
  import React, { useEffect, useRef } from 'react';
2
+ import type { SheetAdapterRef } from './adapter.types';
3
3
 
4
4
  import { Portal } from 'react-native-teleport';
5
5
  import { BottomSheetContext } from './BottomSheet.context';
@@ -30,7 +30,7 @@ export function BottomSheetPersistent({
30
30
  const unmount = useUnmount();
31
31
  const sheetExists = useSheetExists(id);
32
32
  const portalSession = useSheetPortalSession(id);
33
- const sheetRef = useRef<BottomSheetMethods>(null);
33
+ const sheetRef = useRef<SheetAdapterRef>(null);
34
34
  const groupId = bottomSheetManagerContext?.groupId || 'default';
35
35
 
36
36
  const mountSheet = useEvent(() => {
@@ -1,7 +1,5 @@
1
- import { createContext, useContext, type RefObject } from 'react';
2
- import type { BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
3
-
4
- type SheetRef = RefObject<BottomSheetMethods | null>;
1
+ import { createContext, useContext } from 'react';
2
+ import type { SheetRef } from './adapter.types';
5
3
 
6
4
  /**
7
5
  * Context for passing sheet ref from BottomSheetPersistent/BottomSheetPortal
package/src/QueueItem.tsx CHANGED
@@ -43,8 +43,10 @@ export const QueueItem = memo(function QueueItem({
43
43
  };
44
44
  }, [id, keepMounted]);
45
45
 
46
- const backdropZIndex = stackIndex * 2;
47
- const contentZIndex = stackIndex * 2 + 1;
46
+ const baseZIndex = 100_000_000;
47
+
48
+ const backdropZIndex = baseZIndex + stackIndex * 2;
49
+ const contentZIndex = baseZIndex + stackIndex * 2 + 1;
48
50
 
49
51
  if (!animatedIndex) {
50
52
  return null;
@@ -0,0 +1,35 @@
1
+ import type { RefObject } from 'react';
2
+
3
+ /**
4
+ * Minimal ref interface for controlling a sheet/modal/overlay.
5
+ * Every adapter must implement these two methods.
6
+ *
7
+ * The coordinator calls:
8
+ * - `expand()` when status transitions to 'opening'
9
+ * - `close()` when status transitions to 'closing' or 'hidden'
10
+ */
11
+ export interface SheetAdapterRef {
12
+ expand(): void;
13
+ close(): void;
14
+ }
15
+
16
+ /**
17
+ * Event handlers that adapters MUST call to sync UI state back to the store.
18
+ * Returned by `createSheetEventHandlers(sheetId)`.
19
+ *
20
+ * Lifecycle:
21
+ * 1. Coordinator calls `ref.expand()` → adapter shows UI
22
+ * 2. Adapter calls `handleOpened()` when show animation completes
23
+ * 3. User dismisses (swipe/backdrop/back) → adapter calls `handleDismiss()`
24
+ * 4. Adapter calls `handleClosed()` when hide animation completes
25
+ */
26
+ export interface SheetAdapterEvents {
27
+ /** User-initiated dismiss (swipe down, backdrop tap, hardware back button) */
28
+ handleDismiss(): void;
29
+ /** Show animation completed — sheet is fully visible and interactive */
30
+ handleOpened(): void;
31
+ /** Hide animation completed — sheet is fully hidden */
32
+ handleClosed(): void;
33
+ }
34
+
35
+ export type SheetRef = RefObject<SheetAdapterRef | null>;
@@ -0,0 +1,83 @@
1
+ import React, { useImperativeHandle, useRef } from 'react';
2
+
3
+ import type { SheetAdapterRef } from '../../adapter.types';
4
+ import { createSheetEventHandlers } from '../../bottomSheetCoordinator';
5
+ import { useAdapterRef } from '../../useAdapterRef';
6
+ import { useAnimatedIndex } from '../../useAnimatedIndex';
7
+ import { useBottomSheetContext } from '../../useBottomSheetContext';
8
+
9
+ const ActionSheet = require('react-native-actions-sheet').default;
10
+
11
+ /**
12
+ * Adapter for `react-native-actions-sheet` — a zero-dependency action sheet
13
+ * with snap points and gesture controls.
14
+ *
15
+ * All ActionSheet props are accepted via spread and forwarded to the
16
+ * underlying component. Uses `isModal={false}` internally — the stack
17
+ * manager handles the overlay lifecycle.
18
+ *
19
+ * Requires `react-native-actions-sheet` as a peer dependency:
20
+ * ```
21
+ * npm install react-native-actions-sheet
22
+ * ```
23
+ *
24
+ * @see https://github.com/ammarahm-ed/react-native-actions-sheet
25
+ */
26
+ export interface ActionsSheetAdapterProps {
27
+ children: React.ReactNode;
28
+ [key: string]: unknown;
29
+ }
30
+
31
+ export const ActionsSheetAdapter = React.forwardRef<
32
+ SheetAdapterRef,
33
+ ActionsSheetAdapterProps
34
+ >(({ children, ...sheetProps }, forwardedRef) => {
35
+ const { id } = useBottomSheetContext();
36
+ const ref = useAdapterRef(forwardedRef);
37
+ const animatedIndex = useAnimatedIndex();
38
+
39
+ const actionSheetRef = useRef<any>(null);
40
+
41
+ const { handleDismiss, handleOpened, handleClosed } =
42
+ createSheetEventHandlers(id);
43
+
44
+ useImperativeHandle(
45
+ ref,
46
+ () => ({
47
+ expand: () => actionSheetRef.current?.show(),
48
+ close: () => actionSheetRef.current?.hide(),
49
+ }),
50
+ []
51
+ );
52
+
53
+ const onOpen = () => {
54
+ animatedIndex.set(0);
55
+ handleOpened();
56
+ };
57
+
58
+ const onClose = () => {
59
+ animatedIndex.set(-1);
60
+ handleClosed();
61
+ };
62
+
63
+ return (
64
+ <ActionSheet
65
+ // Adapter defaults (overridable via spread)
66
+ gestureEnabled
67
+ closeOnTouchBackdrop
68
+ closeOnPressBack
69
+ keyboardHandlerEnabled
70
+ {...sheetProps}
71
+ // Managed by adapter (not overridable)
72
+ ref={actionSheetRef}
73
+ isModal={false}
74
+ onOpen={onOpen}
75
+ onClose={onClose}
76
+ onBeforeClose={handleDismiss}
77
+ >
78
+ {children}
79
+ </ActionSheet>
80
+ );
81
+ });
82
+
83
+ ActionsSheetAdapter.displayName = 'ActionsSheetAdapter';
@@ -0,0 +1,4 @@
1
+ export {
2
+ ActionsSheetAdapter,
3
+ type ActionsSheetAdapterProps,
4
+ } from './ActionsSheetAdapter';
@@ -0,0 +1,131 @@
1
+ import React, { useEffect, useImperativeHandle, useState } from 'react';
2
+ import {
3
+ BackHandler,
4
+ StyleSheet,
5
+ type StyleProp,
6
+ type ViewStyle,
7
+ } from 'react-native';
8
+ import Animated, {
9
+ useAnimatedReaction,
10
+ useAnimatedStyle,
11
+ useSharedValue,
12
+ withTiming,
13
+ } from 'react-native-reanimated';
14
+ import { scheduleOnRN } from 'react-native-worklets';
15
+
16
+ import type { SheetAdapterRef } from '../../adapter.types';
17
+ import { createSheetEventHandlers } from '../../bottomSheetCoordinator';
18
+ import { useAdapterRef } from '../../useAdapterRef';
19
+ import { useAnimatedIndex } from '../../useAnimatedIndex';
20
+ import { useBottomSheetContext } from '../../useBottomSheetContext';
21
+
22
+ const ANIMATION_DURATION = 300;
23
+
24
+ const ZOOM_INITIAL_SCALE = 0.85;
25
+
26
+ export interface ModalAdapterProps {
27
+ children: React.ReactNode;
28
+ contentContainerStyle?: StyleProp<ViewStyle>;
29
+ }
30
+
31
+ export const CustomModalAdapter = React.forwardRef<
32
+ SheetAdapterRef,
33
+ ModalAdapterProps
34
+ >(({ children, contentContainerStyle }, forwardedRef) => {
35
+ const { id } = useBottomSheetContext();
36
+ const ref = useAdapterRef(forwardedRef);
37
+ const animatedIndex = useAnimatedIndex();
38
+ const [rendered, setRendered] = useState(false);
39
+ const [open, setOpen] = useState(false);
40
+
41
+ const progress = useSharedValue(0);
42
+
43
+ const { handleDismiss, handleOpened, handleClosed } =
44
+ createSheetEventHandlers(id);
45
+
46
+ useImperativeHandle(
47
+ ref,
48
+ () => ({
49
+ expand: () => {
50
+ setRendered(true);
51
+ setOpen(true);
52
+ animatedIndex.set(0);
53
+ },
54
+ close: () => {
55
+ setOpen(false);
56
+ animatedIndex.set(-1);
57
+ },
58
+ }),
59
+ [animatedIndex]
60
+ );
61
+
62
+ const onAnimationEnd = (value: boolean) => {
63
+ 'worklet';
64
+ if (value) {
65
+ scheduleOnRN(handleOpened);
66
+ } else {
67
+ scheduleOnRN(setRendered, false);
68
+ scheduleOnRN(handleClosed);
69
+ }
70
+ };
71
+
72
+ useAnimatedReaction(
73
+ () => open,
74
+ (value, prevValue) => {
75
+ if (prevValue === null || value === prevValue) return;
76
+ progress.value = withTiming(
77
+ value ? 1 : 0,
78
+ { duration: ANIMATION_DURATION },
79
+ (finished) => {
80
+ if (!finished) return;
81
+ onAnimationEnd(value);
82
+ }
83
+ );
84
+ }
85
+ );
86
+
87
+ useEffect(() => {
88
+ if (!rendered) return;
89
+ const subscription = BackHandler.addEventListener(
90
+ 'hardwareBackPress',
91
+ () => {
92
+ handleDismiss();
93
+ return true;
94
+ }
95
+ );
96
+ return () => subscription.remove();
97
+ }, [rendered, handleDismiss]);
98
+
99
+ const animatedStyle = useAnimatedStyle(() => {
100
+ return {
101
+ opacity: progress.value,
102
+ transform: [
103
+ {
104
+ scale: ZOOM_INITIAL_SCALE + progress.value * (1 - ZOOM_INITIAL_SCALE),
105
+ },
106
+ ],
107
+ };
108
+ });
109
+
110
+ if (!rendered) {
111
+ return null;
112
+ }
113
+
114
+ return (
115
+ <Animated.View
116
+ style={[styles.container, contentContainerStyle, animatedStyle]}
117
+ >
118
+ {children}
119
+ </Animated.View>
120
+ );
121
+ });
122
+
123
+ CustomModalAdapter.displayName = 'CustomModalAdapter';
124
+
125
+ const styles = StyleSheet.create({
126
+ container: {
127
+ ...StyleSheet.absoluteFillObject,
128
+ justifyContent: 'center',
129
+ alignItems: 'center',
130
+ },
131
+ });
@@ -0,0 +1,7 @@
1
+ export {
2
+ CustomModalAdapter,
3
+ type ModalAdapterProps,
4
+ } from './CustomModalAdapter';
5
+
6
+ /** @deprecated Use `CustomModalAdapter` instead. */
7
+ export { CustomModalAdapter as ModalAdapter } from './CustomModalAdapter';
@@ -0,0 +1,118 @@
1
+ import BottomSheetOriginal, {
2
+ useBottomSheetSpringConfigs,
3
+ type BottomSheetProps,
4
+ } from '@gorhom/bottom-sheet';
5
+ import React, { useImperativeHandle, useRef } from 'react';
6
+ import { useAnimatedReaction } from 'react-native-reanimated';
7
+
8
+ import type { SheetAdapterRef } from '../../adapter.types';
9
+ import { createSheetEventHandlers } from '../../bottomSheetCoordinator';
10
+ import { useBottomSheetDefaultIndex } from '../../BottomSheetDefaultIndex.context';
11
+ import { useAdapterRef } from '../../useAdapterRef';
12
+ import { useAnimatedIndex } from '../../useAnimatedIndex';
13
+ import { useBottomSheetContext } from '../../useBottomSheetContext';
14
+ import type { BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
15
+
16
+ export interface GorhomSheetAdapterProps extends BottomSheetProps {}
17
+
18
+ const nullBackdrop = () => null;
19
+
20
+ export const GorhomSheetAdapter = React.forwardRef<
21
+ SheetAdapterRef,
22
+ GorhomSheetAdapterProps
23
+ >(
24
+ (
25
+ {
26
+ children,
27
+ onAnimate,
28
+ onChange,
29
+ onClose,
30
+ enablePanDownToClose = true,
31
+ backdropComponent = nullBackdrop,
32
+ animatedIndex: externalAnimatedIndex,
33
+ ...props
34
+ },
35
+ forwardedRef
36
+ ) => {
37
+ const { id } = useBottomSheetContext();
38
+ const ref = useAdapterRef(forwardedRef);
39
+ const contextAnimatedIndex = useAnimatedIndex();
40
+ const defaultIndex = useBottomSheetDefaultIndex();
41
+
42
+ const gorhomRef = useRef<BottomSheetMethods | null>(null);
43
+
44
+ useImperativeHandle(
45
+ ref,
46
+ () => ({
47
+ expand: () => gorhomRef.current?.expand(),
48
+ close: () => gorhomRef.current?.close(),
49
+ }),
50
+ []
51
+ );
52
+
53
+ useAnimatedReaction(
54
+ () => contextAnimatedIndex.value,
55
+ (value) => {
56
+ externalAnimatedIndex?.set(value);
57
+ }
58
+ );
59
+
60
+ const { handleDismiss, handleOpened, handleClosed } =
61
+ createSheetEventHandlers(id);
62
+
63
+ const wrappedOnAnimate: BottomSheetProps['onAnimate'] = (
64
+ fromIndex,
65
+ toIndex,
66
+ fromPosition,
67
+ toPosition
68
+ ) => {
69
+ // toIndex === -1 means gorhom is animating toward closed state
70
+ if (toIndex === -1) {
71
+ handleDismiss();
72
+ }
73
+ onAnimate?.(fromIndex, toIndex, fromPosition, toPosition);
74
+ };
75
+
76
+ const wrappedOnChange: BottomSheetProps['onChange'] = (
77
+ index,
78
+ position,
79
+ type
80
+ ) => {
81
+ // index >= 0 means sheet reached a valid snap point (opened)
82
+ if (index >= 0) {
83
+ handleOpened();
84
+ }
85
+ onChange?.(index, position, type);
86
+ };
87
+
88
+ const wrappedOnClose = () => {
89
+ onClose?.();
90
+ handleClosed();
91
+ };
92
+
93
+ const config = useBottomSheetSpringConfigs({
94
+ stiffness: 400,
95
+ damping: 80,
96
+ mass: 0.7,
97
+ });
98
+
99
+ return (
100
+ <BottomSheetOriginal
101
+ animationConfigs={config}
102
+ ref={gorhomRef}
103
+ {...props}
104
+ index={defaultIndex}
105
+ animatedIndex={contextAnimatedIndex}
106
+ onChange={wrappedOnChange}
107
+ onClose={wrappedOnClose}
108
+ onAnimate={wrappedOnAnimate}
109
+ backdropComponent={backdropComponent}
110
+ enablePanDownToClose={enablePanDownToClose}
111
+ >
112
+ {children}
113
+ </BottomSheetOriginal>
114
+ );
115
+ }
116
+ );
117
+
118
+ GorhomSheetAdapter.displayName = 'GorhomSheetAdapter';
@@ -0,0 +1,4 @@
1
+ export {
2
+ GorhomSheetAdapter,
3
+ type GorhomSheetAdapterProps,
4
+ } from './GorhomSheetAdapter';
@@ -0,0 +1,17 @@
1
+ export {
2
+ GorhomSheetAdapter,
3
+ type GorhomSheetAdapterProps,
4
+ } from './gorhom-sheet';
5
+ export {
6
+ CustomModalAdapter,
7
+ ModalAdapter,
8
+ type ModalAdapterProps,
9
+ } from './custom-modal';
10
+ export {
11
+ ReactNativeModalAdapter,
12
+ type ReactNativeModalAdapterProps,
13
+ } from './react-native-modal';
14
+ export {
15
+ ActionsSheetAdapter,
16
+ type ActionsSheetAdapterProps,
17
+ } from './actions-sheet';