@niibase/bottom-sheet-manager 1.2.0 → 1.4.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 (64) hide show
  1. package/README.md +414 -69
  2. package/lib/commonjs/events.js +100 -15
  3. package/lib/commonjs/events.js.map +1 -1
  4. package/lib/commonjs/index.js +14 -0
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/manager.js +153 -35
  7. package/lib/commonjs/manager.js.map +1 -1
  8. package/lib/commonjs/provider.js +92 -54
  9. package/lib/commonjs/provider.js.map +1 -1
  10. package/lib/commonjs/router/index.js +80 -21
  11. package/lib/commonjs/router/index.js.map +1 -1
  12. package/lib/commonjs/router/router.js +137 -12
  13. package/lib/commonjs/router/router.js.map +1 -1
  14. package/lib/commonjs/router/view.js +93 -126
  15. package/lib/commonjs/router/view.js.map +1 -1
  16. package/lib/commonjs/sheet.js +122 -98
  17. package/lib/commonjs/sheet.js.map +1 -1
  18. package/lib/module/events.js +100 -15
  19. package/lib/module/events.js.map +1 -1
  20. package/lib/module/index.js +2 -2
  21. package/lib/module/index.js.map +1 -1
  22. package/lib/module/manager.js +154 -35
  23. package/lib/module/manager.js.map +1 -1
  24. package/lib/module/provider.js +87 -50
  25. package/lib/module/provider.js.map +1 -1
  26. package/lib/module/router/index.js +66 -19
  27. package/lib/module/router/index.js.map +1 -1
  28. package/lib/module/router/router.js +135 -11
  29. package/lib/module/router/router.js.map +1 -1
  30. package/lib/module/router/view.js +92 -126
  31. package/lib/module/router/view.js.map +1 -1
  32. package/lib/module/sheet.js +124 -100
  33. package/lib/module/sheet.js.map +1 -1
  34. package/lib/typescript/events.d.ts +46 -12
  35. package/lib/typescript/events.d.ts.map +1 -1
  36. package/lib/typescript/index.d.ts +2 -2
  37. package/lib/typescript/index.d.ts.map +1 -1
  38. package/lib/typescript/manager.d.ts +73 -7
  39. package/lib/typescript/manager.d.ts.map +1 -1
  40. package/lib/typescript/provider.d.ts +22 -16
  41. package/lib/typescript/provider.d.ts.map +1 -1
  42. package/lib/typescript/router/index.d.ts +47 -17
  43. package/lib/typescript/router/index.d.ts.map +1 -1
  44. package/lib/typescript/router/router.d.ts +44 -5
  45. package/lib/typescript/router/router.d.ts.map +1 -1
  46. package/lib/typescript/router/types.d.ts +142 -32
  47. package/lib/typescript/router/types.d.ts.map +1 -1
  48. package/lib/typescript/router/view.d.ts +3 -3
  49. package/lib/typescript/router/view.d.ts.map +1 -1
  50. package/lib/typescript/sheet.d.ts +1 -1
  51. package/lib/typescript/sheet.d.ts.map +1 -1
  52. package/lib/typescript/types.d.ts +52 -21
  53. package/lib/typescript/types.d.ts.map +1 -1
  54. package/package.json +14 -15
  55. package/src/events.ts +118 -27
  56. package/src/index.ts +2 -1
  57. package/src/manager.ts +209 -42
  58. package/src/provider.tsx +144 -71
  59. package/src/router/index.tsx +77 -33
  60. package/src/router/router.ts +188 -15
  61. package/src/router/types.ts +172 -57
  62. package/src/router/view.tsx +111 -213
  63. package/src/sheet.tsx +192 -124
  64. package/src/types.ts +51 -24
package/src/provider.tsx CHANGED
@@ -1,7 +1,3 @@
1
- import { useSafeAreaInsets } from "react-native-safe-area-context";
2
- import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
3
- import { StatusBar } from "react-native";
4
- import React from "react";
5
1
  import Animated, {
6
2
  interpolate,
7
3
  interpolateColor,
@@ -13,8 +9,18 @@ import Animated, {
13
9
  withSpring,
14
10
  withTiming,
15
11
  } from "react-native-reanimated";
12
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
13
+ import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
14
+ import { StatusBar } from "react-native";
15
+ import React from "react";
16
16
 
17
- import { BottomSheetInstance, SheetPayload, Sheets } from "./types";
17
+ import {
18
+ BottomSheetInstance,
19
+ SheetPayload,
20
+ SheetProviderProps,
21
+ Sheets,
22
+ StackBehavior,
23
+ } from "./types";
18
24
  import { eventManager } from "./events";
19
25
 
20
26
  export const providerRegistryStack: string[] = [];
@@ -46,7 +52,7 @@ export function registerSheet<SheetId extends keyof Sheets = never>(
46
52
  ? (sheetsRegistry[context] = {})
47
53
  : sheetsRegistry[context];
48
54
  registry[id as string] = Sheet;
49
- eventManager.publish(`${context}-on-register`);
55
+ eventManager.publishAsync(`${context}-on-register`);
50
56
  }
51
57
  }
52
58
 
@@ -55,36 +61,28 @@ export function registerSheet<SheetId extends keyof Sheets = never>(
55
61
  * `global`. However if you want to render a Sheet within another sheet or if you want to render
56
62
  * Sheets in a modal. You can use a separate Provider with a custom context value.
57
63
  *
58
- * For example
64
+ * > **Note:** Context names must be unique across all `SheetProvider` instances.
65
+ *
66
+ * @example
59
67
  * ```ts
60
68
  * // Define your SheetProvider in the component/modal where
61
69
  * // you want to show some Sheets.
62
70
  * <SheetProvider context="local-context" />
63
71
  *
64
- * // Then register your sheet when for example the
65
- * // Modal component renders.
66
- *
67
- * registerSheet('local-sheet', LocalSheet,'local-context');
68
- *
72
+ * // Then register your sheet at module level (outside JSX):
73
+ * registerSheet('local-sheet', LocalSheet, 'local-context');
69
74
  * ```
70
75
  */
71
76
  export function SheetProvider({
72
- iosModalSheetTypeOfAnimation = false,
73
77
  context = "global",
74
- duration = 300,
78
+ statusBar,
79
+ scaleConfig,
75
80
  children,
76
- }: React.PropsWithChildren<{
77
- context?: string;
78
- duration?: number;
79
- iosModalSheetTypeOfAnimation?: boolean;
80
- }>) {
81
+ }: SheetProviderProps) {
81
82
  const { top } = useSafeAreaInsets();
82
83
  const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
83
84
  const sheetIds = Object.keys(sheetsRegistry[context] || sheetsRegistry["global"] || {});
84
85
 
85
- // Rerender when a new sheet is added.
86
- const onRegister = React.useCallback(forceUpdate, [forceUpdate]);
87
-
88
86
  // IOS modal sheet type of animation
89
87
  const isFullScreen = useSharedValue(-1);
90
88
  const colorStyle = useAnimatedStyle(() => ({
@@ -95,28 +93,52 @@ export function SheetProvider({
95
93
  ["transparent", "#000"],
96
94
  ),
97
95
  }));
98
- const animatedStyle = useAnimatedStyle(
99
- () => ({
96
+ const animatedStyle = useAnimatedStyle(() => {
97
+ const radius = interpolate(
98
+ isFullScreen.value,
99
+ [0, 0.3],
100
+ [0, scaleConfig?.borderRadius ?? 24],
101
+ "clamp",
102
+ );
103
+ const scale = interpolate(
104
+ isFullScreen.value,
105
+ [0.5, 0.8],
106
+ [1, scaleConfig?.scale ?? 0.92],
107
+ "clamp",
108
+ );
109
+ const translateY = interpolate(
110
+ isFullScreen.value,
111
+ [0.5, 0.7],
112
+ [0, top + (scaleConfig?.translateY ?? 5)],
113
+ "clamp",
114
+ );
115
+
116
+ return {
100
117
  flex: 1,
101
118
  overflow: "hidden",
102
- borderRadius: interpolate(isFullScreen.value, [0, 0.8, 1], [0, 20, 24], "clamp"),
119
+ borderRadius:
120
+ scaleConfig?.animation?.type === "spring"
121
+ ? withSpring(radius, scaleConfig.animation.config)
122
+ : withTiming(radius, scaleConfig?.animation?.config ?? { duration: 200 }),
103
123
  transform: [
104
124
  {
105
- scaleX: withTiming(
106
- interpolate(isFullScreen.value, [0, 0.98, 1], [1, 1, 0.92], "clamp"),
107
- { duration },
108
- ),
125
+ scaleX:
126
+ scaleConfig?.animation?.type === "spring"
127
+ ? withSpring(scale, scaleConfig.animation.config)
128
+ : withTiming(scale, scaleConfig?.animation?.config ?? { duration: 200 }),
109
129
  },
110
130
  {
111
- translateY: withSpring(
112
- interpolate(isFullScreen.value, [0, 0.99, 1], [0, top, top + 5], "clamp"),
113
- { duration, dampingRatio: 1.5 },
114
- ),
131
+ translateY:
132
+ scaleConfig?.animation?.type === "spring"
133
+ ? withSpring(translateY, scaleConfig.animation.config)
134
+ : withTiming(
135
+ translateY,
136
+ scaleConfig?.animation?.config ?? { duration: 200 },
137
+ ),
115
138
  },
116
139
  ],
117
- }),
118
- [duration],
119
- );
140
+ };
141
+ }, [top, scaleConfig]);
120
142
 
121
143
  // Since background color is white, we need to set status bar to light
122
144
  const setStatusBar = StatusBar.setBarStyle;
@@ -124,8 +146,11 @@ export function SheetProvider({
124
146
  () => isFullScreen.value,
125
147
  (currentValue) => {
126
148
  "worklet";
127
- if (currentValue > -1) {
128
- runOnJS(setStatusBar)(currentValue >= 0.5 ? "light-content" : "default");
149
+ if (currentValue >= 0) {
150
+ runOnJS(setStatusBar)(
151
+ currentValue >= 0.5 ? "light-content" : (statusBar ?? "default"),
152
+ true,
153
+ );
129
154
  }
130
155
  },
131
156
  [],
@@ -135,40 +160,55 @@ export function SheetProvider({
135
160
  providerRegistryStack.indexOf(context) > -1
136
161
  ? providerRegistryStack.indexOf(context)
137
162
  : providerRegistryStack.push(context) - 1;
138
- const unsub = eventManager.subscribe(`${context}-on-register`, onRegister);
163
+ const unsub = eventManager.subscribe(`${context}-on-register`, forceUpdate);
139
164
  return () => {
140
165
  providerRegistryStack.splice(providerRegistryStack.indexOf(context), 1);
141
166
  unsub?.unsubscribe();
142
167
  };
143
- }, [context, onRegister]);
168
+ }, [context, forceUpdate]);
144
169
 
145
170
  return (
146
- <SheetAnimationContext.Provider
147
- value={{ isFullScreen, iosModalSheetTypeOfAnimation }}
148
- >
171
+ <SheetSharedContext.Provider value={{ isFullScreen, topInset: top }}>
149
172
  <Animated.View style={colorStyle}>
150
173
  <Animated.View style={animatedStyle}>{children}</Animated.View>
151
174
  </Animated.View>
152
175
  <BottomSheetModalProvider>
153
176
  {sheetIds.map((id) => (
154
- <RenderSheet key={id} id={id} context={context} duration={duration} />
177
+ <RenderSheet key={id} id={id} context={context} />
155
178
  ))}
156
179
  </BottomSheetModalProvider>
157
- </SheetAnimationContext.Provider>
180
+ </SheetSharedContext.Provider>
158
181
  );
159
182
  }
183
+
160
184
  const ProviderContext = React.createContext("global");
161
185
  const SheetIDContext = React.createContext<string | undefined>(undefined);
162
- const SheetAnimationContext = React.createContext<{
163
- iosModalSheetTypeOfAnimation: boolean;
186
+ const SheetSharedContext = React.createContext<{
164
187
  isFullScreen: SharedValue<number>;
165
- }>({ isFullScreen: { value: 0 } as any, iosModalSheetTypeOfAnimation: false });
188
+ topInset: number;
189
+ }>({
190
+ isFullScreen: { value: 0 } as SharedValue<number>,
191
+ topInset: 0,
192
+ });
166
193
 
167
194
  export const SheetRefContext = React.createContext<
168
195
  React.RefObject<BottomSheetInstance | null>
169
- >({} as any);
196
+ >({} as React.RefObject<BottomSheetInstance | null>);
170
197
 
171
- const SheetPayloadContext = React.createContext<any>(undefined);
198
+ const SheetPayloadContext = React.createContext<unknown>(undefined);
199
+
200
+ // Stack behavior context for managing sheet transitions
201
+ interface StackBehaviorContextValue {
202
+ behavior: StackBehavior;
203
+ isTransitioning: boolean;
204
+ previousSheetId: string | null;
205
+ }
206
+
207
+ const StackBehaviorContext = React.createContext<StackBehaviorContextValue>({
208
+ behavior: "switch",
209
+ isTransitioning: false,
210
+ previousSheetId: null,
211
+ });
172
212
 
173
213
  /**
174
214
  * Get id of the current context.
@@ -181,9 +221,14 @@ export const useSheetIDContext = () => React.useContext(SheetIDContext);
181
221
  /**
182
222
  * Get the current sheet animation context.
183
223
  */
184
- export const useSheetAnimationContext = () => React.useContext(SheetAnimationContext);
224
+ export const useSheetSharedContext = () => React.useContext(SheetSharedContext);
225
+ /**
226
+ * Get stack behavior context for the current sheet.
227
+ */
228
+ export const useStackBehaviorContext = () => React.useContext(StackBehaviorContext);
185
229
  /**
186
230
  * Get the current Sheet's internal ref.
231
+ * Note: `current` may be null before the sheet is fully mounted.
187
232
  */
188
233
  export const useSheetRef = <
189
234
  SheetId extends keyof Sheets = never,
@@ -205,25 +250,26 @@ export function useSheetPayload<SheetId extends keyof Sheets = never>() {
205
250
  export function useOnSheet<SheetId extends keyof Sheets = never>(
206
251
  id: SheetId | (string & {}),
207
252
  type: "show" | "hide" | "onclose",
208
- listener: (payload: SheetPayload<SheetId>, context: string, ...args: any[]) => void,
253
+ listener: (payload: SheetPayload<SheetId>, context: string, ...args: unknown[]) => void,
209
254
  ) {
210
255
  React.useEffect(() => {
211
256
  const subscription = eventManager.subscribe(`${type}_${id}`, listener);
212
257
  return () => subscription.unsubscribe();
213
- }, [id, listener]);
258
+ }, [id, listener, type]);
214
259
  }
215
260
 
216
- const RenderSheet = ({
217
- id,
218
- context,
219
- duration,
220
- }: {
261
+ interface RenderSheetProps {
221
262
  id: string;
222
263
  context: string;
223
- duration: number;
224
- }) => {
225
- const [payload, setPayload] = React.useState();
264
+ }
265
+
266
+ const RenderSheet = ({ id, context }: RenderSheetProps) => {
267
+ const [payload, setPayload] = React.useState<unknown>();
226
268
  const [visible, setVisible] = React.useState(false);
269
+ const [stackBehavior, setStackBehavior] = React.useState<StackBehavior>("switch");
270
+ const [isPending, startTransition] = React.useTransition();
271
+ const [previousSheetId, setPreviousSheetId] = React.useState<string | null>(null);
272
+
227
273
  const ref = React.useRef<BottomSheetInstance | null>(null);
228
274
  const Sheet = context.startsWith("$$-auto-")
229
275
  ? sheetsRegistry?.global?.[id]
@@ -232,29 +278,46 @@ const RenderSheet = ({
232
278
  : undefined;
233
279
 
234
280
  const onShow = React.useCallback(
235
- (data: any, ctx = "global", reopened?: boolean) => {
281
+ (data: unknown, ctx = "global", reopened?: boolean, behavior?: StackBehavior) => {
236
282
  if (ctx !== context) return;
237
- if (!reopened) setPayload(data);
238
- setVisible(true);
283
+
284
+ if (behavior) {
285
+ setStackBehavior(behavior);
286
+ }
287
+
288
+ if (!reopened) {
289
+ setPayload(data);
290
+ }
291
+
292
+ // Smooth transition handling using React's useTransition
293
+ startTransition(() => {
294
+ setVisible(true);
295
+ });
239
296
  },
240
297
  [context],
241
298
  );
242
299
 
243
300
  const onClose = React.useCallback(
244
- (_data: any, ctx = "global", reopened?: boolean) => {
301
+ (_data: unknown, ctx = "global", reopened?: boolean, nextSheetId?: string) => {
245
302
  if (context !== ctx) return;
303
+
304
+ if (nextSheetId) {
305
+ setPreviousSheetId(nextSheetId);
306
+ }
307
+
246
308
  if (!reopened) {
247
309
  setPayload(undefined);
248
- setTimeout(() => setVisible(false), Math.max(duration ?? 300, 300));
310
+ setVisible(false);
249
311
  } else {
250
312
  setVisible(false);
313
+ setPreviousSheetId(null);
251
314
  }
252
315
  },
253
316
  [context],
254
317
  );
255
318
 
256
319
  const onHide = React.useCallback(
257
- (data: any, ctx = "global") => {
320
+ (data: unknown, ctx = "global") => {
258
321
  eventManager.publish(`hide_${id}`, data, ctx);
259
322
  },
260
323
  [id],
@@ -267,7 +330,7 @@ const RenderSheet = ({
267
330
  }, [context, id, payload, visible]);
268
331
 
269
332
  React.useEffect(() => {
270
- let subs = [
333
+ const subs = [
271
334
  eventManager.subscribe(`show_wrap_${id}`, onShow),
272
335
  eventManager.subscribe(`onclose_${id}`, onClose),
273
336
  eventManager.subscribe(`hide_wrap_${id}`, onHide),
@@ -279,15 +342,25 @@ const RenderSheet = ({
279
342
 
280
343
  if (!Sheet) return null;
281
344
 
282
- return visible ? (
345
+ const stackContextValue: StackBehaviorContextValue = {
346
+ behavior: stackBehavior,
347
+ isTransitioning: isPending,
348
+ previousSheetId,
349
+ };
350
+
351
+ if (!visible) return null;
352
+
353
+ return (
283
354
  <ProviderContext.Provider value={context}>
284
355
  <SheetIDContext.Provider value={id}>
285
356
  <SheetRefContext.Provider value={ref}>
286
357
  <SheetPayloadContext.Provider value={payload}>
287
- <Sheet id={id} payload={payload} context={context} />
358
+ <StackBehaviorContext.Provider value={stackContextValue}>
359
+ <Sheet id={id} payload={payload} context={context} />
360
+ </StackBehaviorContext.Provider>
288
361
  </SheetPayloadContext.Provider>
289
362
  </SheetRefContext.Provider>
290
363
  </SheetIDContext.Provider>
291
364
  </ProviderContext.Provider>
292
- ) : null;
365
+ );
293
366
  };
@@ -1,14 +1,15 @@
1
1
  import {
2
2
  createNavigatorFactory,
3
- NavigatorTypeBagBase,
4
- ParamListBase,
5
- StaticConfig,
6
- TypedNavigator,
3
+ EventArg,
4
+ StackActions,
7
5
  useNavigationBuilder,
6
+ type NavigatorTypeBagBase,
7
+ type ParamListBase,
8
+ type StaticConfig,
9
+ type TypedNavigator,
8
10
  } from "@react-navigation/native";
9
- import React from "react";
11
+ import * as React from "react";
10
12
 
11
- import { BottomSheetRouter, BottomSheetRouterOptions } from "./router";
12
13
  import type {
13
14
  BottomSheetActionHelpers,
14
15
  BottomSheetNavigationEventMap,
@@ -17,13 +18,23 @@ import type {
17
18
  BottomSheetNavigationState,
18
19
  BottomSheetNavigatorProps,
19
20
  } from "./types";
21
+ import { BottomSheetRouter, type BottomSheetRouterOptions } from "./router";
20
22
  import { BottomSheetView } from "./view";
21
23
 
22
- function BottomSheetNavigator({
24
+ /**
25
+ * Unified Navigator that renders the first screen as the base content
26
+ * and all subsequent screens as bottom sheet overlays.
27
+ *
28
+ * Uses BottomSheetRouter (extending StackRouter) to manage navigation state,
29
+ * with react-native-screens ScreenStack for the base screen rendering
30
+ * and BottomSheetView for the sheet overlays.
31
+ */
32
+ function Navigator({
23
33
  id,
24
34
  children,
25
35
  screenListeners,
26
36
  screenOptions,
37
+ initialRouteName,
27
38
  ...rest
28
39
  }: BottomSheetNavigatorProps) {
29
40
  const { state, descriptors, navigation, NavigationContent } = useNavigationBuilder<
@@ -37,8 +48,30 @@ function BottomSheetNavigator({
37
48
  children,
38
49
  screenListeners,
39
50
  screenOptions,
51
+ initialRouteName,
40
52
  });
41
53
 
54
+ // Handle tab press → popToTop behavior
55
+ React.useEffect(() => {
56
+ // @ts-expect-error: there may not be a tab navigator in parent
57
+ return navigation?.addListener?.("tabPress", (e: any) => {
58
+ const isFocused = navigation.isFocused();
59
+
60
+ requestAnimationFrame(() => {
61
+ if (
62
+ state.index > 0 &&
63
+ isFocused &&
64
+ !(e as EventArg<"tabPress", true>).defaultPrevented
65
+ ) {
66
+ navigation.dispatch({
67
+ ...StackActions.popToTop(),
68
+ target: state.key,
69
+ });
70
+ }
71
+ });
72
+ });
73
+ }, [navigation, state.index, state.key]);
74
+
42
75
  return (
43
76
  <NavigationContent>
44
77
  <BottomSheetView
@@ -52,18 +85,38 @@ function BottomSheetNavigator({
52
85
  }
53
86
 
54
87
  /**
55
- * To use BottomSheetNavigator with expo-router, the first screen should be your app content
56
- * and add a border radius of 24px to the root view if want to snap to 100%.
88
+ * Creates a bottom sheet navigator that renders the first screen as the
89
+ * main content and all subsequent screens as bottom sheet modals.
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * // With React Navigation
94
+ * const { Navigator, Screen } = createBottomSheetNavigator();
95
+ *
96
+ * function App() {
97
+ * return (
98
+ * <Navigator>
99
+ * <Screen name="Home" component={HomeScreen} />
100
+ * <Screen
101
+ * name="Details"
102
+ * component={DetailsSheet}
103
+ * options={{ snapPoints: ['50%', '100%'] }}
104
+ * />
105
+ * </Navigator>
106
+ * );
107
+ * }
108
+ * ```
57
109
  *
58
110
  * @example
59
111
  * ```tsx
112
+ * // With Expo Router
113
+ * import { Slot, withLayoutContext } from "expo-router";
60
114
  * import {
61
115
  * createBottomSheetNavigator,
62
116
  * BottomSheetNavigationOptions,
63
117
  * BottomSheetNavigationEventMap,
64
118
  * BottomSheetNavigationState,
65
- * } from "@repo/bottom-sheet";
66
- * import { Slot, withLayoutContext } from "expo-router";
119
+ * } from "@niibase/bottom-sheet-manager";
67
120
  *
68
121
  * const { Navigator } = createBottomSheetNavigator();
69
122
  *
@@ -79,36 +132,30 @@ function BottomSheetNavigator({
79
132
  * };
80
133
  *
81
134
  * export default function Layout() {
135
+ * // SSR guard - navigator doesn't work on server
82
136
  * if (typeof window === "undefined") return <Slot />;
137
+ *
83
138
  * return (
84
- * <BottomSheet
85
- * screenOptions={
86
- * {
87
- * // API Reference: `@repo/design/bottom-sheet/types.ts`
88
- * // And: https://gorhom.github.io/react-native-bottom-sheet/modal/props/
89
- * }
90
- * }
91
- *. />
139
+ * <BottomSheet>
140
+ * <BottomSheet.Screen name="index" />
141
+ * <BottomSheet.Screen
142
+ * name="details"
143
+ * options={{ snapPoints: ["50%"] }}
144
+ * />
145
+ * </BottomSheet>
92
146
  * );
93
147
  * }
94
148
  * ```
95
149
  */
96
150
  export function createBottomSheetNavigator<
97
151
  const ParamList extends ParamListBase,
98
- const NavigatorID extends string | undefined = undefined,
99
- // We'll define a type bag specialized for bottom sheets:
152
+ const NavigatorID extends string | undefined = string | undefined,
100
153
  const TypeBag extends NavigatorTypeBagBase = {
101
- // The param list from the user
102
154
  ParamList: ParamList;
103
- // Optional ID for this navigator
104
155
  NavigatorID: NavigatorID;
105
- // The state shape
106
156
  State: BottomSheetNavigationState<ParamList>;
107
- // The screen options
108
157
  ScreenOptions: BottomSheetNavigationOptions;
109
- // The event map
110
158
  EventMap: BottomSheetNavigationEventMap;
111
- // The type of the "navigation" object used by each screen in the navigator
112
159
  NavigationList: {
113
160
  [RouteName in keyof ParamList]: BottomSheetNavigationProp<
114
161
  ParamList,
@@ -116,15 +163,12 @@ export function createBottomSheetNavigator<
116
163
  NavigatorID
117
164
  >;
118
165
  };
119
- // The navigator component
120
- Navigator: typeof BottomSheetNavigator;
166
+ Navigator: typeof Navigator;
121
167
  },
122
- // The static config allows for "static" route config
123
168
  const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,
124
169
  >(config?: Config): TypedNavigator<TypeBag, Config> {
125
- // We call `createNavigatorFactory` with our un-typed navigator
126
- // but pass in the config to get the typed container
127
- return createNavigatorFactory(BottomSheetNavigator)(config);
170
+ return createNavigatorFactory(Navigator)(config);
128
171
  }
129
172
 
130
173
  export * from "./types";
174
+ export { BottomSheetActions, useBottomSheetNavigation } from "./router";