@niibase/bottom-sheet-manager 1.1.0 → 1.3.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.
- package/README.md +372 -38
- package/lib/commonjs/events.js +100 -15
- package/lib/commonjs/events.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/manager.js +107 -29
- package/lib/commonjs/manager.js.map +1 -1
- package/lib/commonjs/provider.js +69 -28
- package/lib/commonjs/provider.js.map +1 -1
- package/lib/commonjs/router/index.js +50 -21
- package/lib/commonjs/router/index.js.map +1 -1
- package/lib/commonjs/router/router.js +137 -12
- package/lib/commonjs/router/router.js.map +1 -1
- package/lib/commonjs/router/view.js +194 -84
- package/lib/commonjs/router/view.js.map +1 -1
- package/lib/commonjs/sheet.js +125 -76
- package/lib/commonjs/sheet.js.map +1 -1
- package/lib/module/events.js +100 -15
- package/lib/module/events.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/manager.js +108 -29
- package/lib/module/manager.js.map +1 -1
- package/lib/module/provider.js +65 -25
- package/lib/module/provider.js.map +1 -1
- package/lib/module/router/index.js +34 -18
- package/lib/module/router/index.js.map +1 -1
- package/lib/module/router/router.js +135 -11
- package/lib/module/router/router.js.map +1 -1
- package/lib/module/router/view.js +194 -84
- package/lib/module/router/view.js.map +1 -1
- package/lib/module/sheet.js +127 -78
- package/lib/module/sheet.js.map +1 -1
- package/lib/typescript/events.d.ts +46 -12
- package/lib/typescript/events.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/manager.d.ts +57 -7
- package/lib/typescript/manager.d.ts.map +1 -1
- package/lib/typescript/provider.d.ts +22 -3
- package/lib/typescript/provider.d.ts.map +1 -1
- package/lib/typescript/router/index.d.ts +33 -17
- package/lib/typescript/router/index.d.ts.map +1 -1
- package/lib/typescript/router/router.d.ts +44 -5
- package/lib/typescript/router/router.d.ts.map +1 -1
- package/lib/typescript/router/types.d.ts +113 -17
- package/lib/typescript/router/types.d.ts.map +1 -1
- package/lib/typescript/router/view.d.ts +1 -1
- package/lib/typescript/router/view.d.ts.map +1 -1
- package/lib/typescript/sheet.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +27 -12
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/events.ts +118 -27
- package/src/index.ts +6 -5
- package/src/manager.ts +156 -33
- package/src/provider.tsx +98 -44
- package/src/router/index.tsx +38 -31
- package/src/router/router.ts +184 -15
- package/src/router/types.ts +119 -22
- package/src/router/view.tsx +252 -132
- package/src/sheet.tsx +176 -95
- package/src/types.ts +144 -129
package/src/router/index.tsx
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createNavigatorFactory,
|
|
3
|
-
NavigatorTypeBagBase,
|
|
4
|
-
ParamListBase,
|
|
5
|
-
StaticConfig,
|
|
6
|
-
TypedNavigator,
|
|
7
3
|
useNavigationBuilder,
|
|
4
|
+
type NavigatorTypeBagBase,
|
|
5
|
+
type ParamListBase,
|
|
6
|
+
type StaticConfig,
|
|
7
|
+
type TypedNavigator,
|
|
8
8
|
} from "@react-navigation/native";
|
|
9
|
-
import React from "react";
|
|
9
|
+
import * as React from "react";
|
|
10
10
|
|
|
11
|
-
import { BottomSheetRouter, BottomSheetRouterOptions } from "./router";
|
|
12
11
|
import type {
|
|
13
12
|
BottomSheetActionHelpers,
|
|
14
13
|
BottomSheetNavigationEventMap,
|
|
@@ -17,6 +16,7 @@ import type {
|
|
|
17
16
|
BottomSheetNavigationState,
|
|
18
17
|
BottomSheetNavigatorProps,
|
|
19
18
|
} from "./types";
|
|
19
|
+
import { BottomSheetRouter, type BottomSheetRouterOptions } from "./router";
|
|
20
20
|
import { BottomSheetView } from "./view";
|
|
21
21
|
|
|
22
22
|
function BottomSheetNavigator({
|
|
@@ -24,6 +24,7 @@ function BottomSheetNavigator({
|
|
|
24
24
|
children,
|
|
25
25
|
screenListeners,
|
|
26
26
|
screenOptions,
|
|
27
|
+
initialRouteName,
|
|
27
28
|
...rest
|
|
28
29
|
}: BottomSheetNavigatorProps) {
|
|
29
30
|
const { state, descriptors, navigation, NavigationContent } = useNavigationBuilder<
|
|
@@ -37,6 +38,7 @@ function BottomSheetNavigator({
|
|
|
37
38
|
children,
|
|
38
39
|
screenListeners,
|
|
39
40
|
screenOptions,
|
|
41
|
+
initialRouteName,
|
|
40
42
|
});
|
|
41
43
|
|
|
42
44
|
return (
|
|
@@ -52,18 +54,40 @@ function BottomSheetNavigator({
|
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
+
* Creates a bottom sheet navigator that renders screens as bottom sheet modals.
|
|
58
|
+
*
|
|
59
|
+
* The first screen in the navigator is rendered as the main content,
|
|
60
|
+
* and subsequent screens are rendered as bottom sheet modals on top.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* // With React Navigation
|
|
65
|
+
* const { Navigator, Screen } = createBottomSheetNavigator();
|
|
66
|
+
*
|
|
67
|
+
* function App() {
|
|
68
|
+
* return (
|
|
69
|
+
* <Navigator>
|
|
70
|
+
* <Screen name="Home" component={HomeScreen} />
|
|
71
|
+
* <Screen
|
|
72
|
+
* name="Details"
|
|
73
|
+
* component={DetailsSheet}
|
|
74
|
+
* options={{ snapPoints: ['50%', '100%'] }}
|
|
75
|
+
* />
|
|
76
|
+
* </Navigator>
|
|
77
|
+
* );
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
57
80
|
*
|
|
58
81
|
* @example
|
|
59
82
|
* ```tsx
|
|
83
|
+
* // With Expo Router
|
|
84
|
+
* import { Slot, withLayoutContext } from "expo-router";
|
|
60
85
|
* import {
|
|
61
86
|
* createBottomSheetNavigator,
|
|
62
87
|
* BottomSheetNavigationOptions,
|
|
63
88
|
* BottomSheetNavigationEventMap,
|
|
64
89
|
* BottomSheetNavigationState,
|
|
65
|
-
* } from "@
|
|
66
|
-
* import { Slot, withLayoutContext } from "expo-router";
|
|
90
|
+
* } from "@niibase/bottom-sheet-manager";
|
|
67
91
|
*
|
|
68
92
|
* const { Navigator } = createBottomSheetNavigator();
|
|
69
93
|
*
|
|
@@ -79,36 +103,22 @@ function BottomSheetNavigator({
|
|
|
79
103
|
* };
|
|
80
104
|
*
|
|
81
105
|
* export default function Layout() {
|
|
106
|
+
* // SSR guard - navigator doesn't work on server
|
|
82
107
|
* if (typeof window === "undefined") return <Slot />;
|
|
83
|
-
*
|
|
84
|
-
*
|
|
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
|
-
*. />
|
|
92
|
-
* );
|
|
108
|
+
*
|
|
109
|
+
* return <BottomSheet />;
|
|
93
110
|
* }
|
|
94
111
|
* ```
|
|
95
112
|
*/
|
|
96
113
|
export function createBottomSheetNavigator<
|
|
97
114
|
const ParamList extends ParamListBase,
|
|
98
115
|
const NavigatorID extends string | undefined = undefined,
|
|
99
|
-
// We'll define a type bag specialized for bottom sheets:
|
|
100
116
|
const TypeBag extends NavigatorTypeBagBase = {
|
|
101
|
-
// The param list from the user
|
|
102
117
|
ParamList: ParamList;
|
|
103
|
-
// Optional ID for this navigator
|
|
104
118
|
NavigatorID: NavigatorID;
|
|
105
|
-
// The state shape
|
|
106
119
|
State: BottomSheetNavigationState<ParamList>;
|
|
107
|
-
// The screen options
|
|
108
120
|
ScreenOptions: BottomSheetNavigationOptions;
|
|
109
|
-
// The event map
|
|
110
121
|
EventMap: BottomSheetNavigationEventMap;
|
|
111
|
-
// The type of the "navigation" object used by each screen in the navigator
|
|
112
122
|
NavigationList: {
|
|
113
123
|
[RouteName in keyof ParamList]: BottomSheetNavigationProp<
|
|
114
124
|
ParamList,
|
|
@@ -116,15 +126,12 @@ export function createBottomSheetNavigator<
|
|
|
116
126
|
NavigatorID
|
|
117
127
|
>;
|
|
118
128
|
};
|
|
119
|
-
// The navigator component
|
|
120
129
|
Navigator: typeof BottomSheetNavigator;
|
|
121
130
|
},
|
|
122
|
-
// The static config allows for "static" route config
|
|
123
131
|
const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,
|
|
124
132
|
>(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
133
|
return createNavigatorFactory(BottomSheetNavigator)(config);
|
|
128
134
|
}
|
|
129
135
|
|
|
130
136
|
export * from "./types";
|
|
137
|
+
export { BottomSheetActions, useBottomSheetNavigation } from "./router";
|
package/src/router/router.ts
CHANGED
|
@@ -1,57 +1,121 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ParamListBase,
|
|
3
|
-
Router,
|
|
4
2
|
StackActions,
|
|
5
|
-
StackActionType,
|
|
6
3
|
StackRouter,
|
|
7
|
-
|
|
4
|
+
useNavigation,
|
|
5
|
+
type CommonActions,
|
|
6
|
+
type ParamListBase,
|
|
7
|
+
type Router,
|
|
8
|
+
type StackActionType,
|
|
9
|
+
type StackRouterOptions,
|
|
8
10
|
} from "@react-navigation/native";
|
|
9
11
|
import { nanoid } from "nanoid/non-secure";
|
|
10
12
|
|
|
11
|
-
import type { BottomSheetNavigationState } from "./types";
|
|
13
|
+
import type { BottomSheetNavigationProp, BottomSheetNavigationState } from "./types";
|
|
12
14
|
|
|
13
15
|
export type BottomSheetRouterOptions = StackRouterOptions;
|
|
14
16
|
|
|
15
17
|
export type BottomSheetActionType =
|
|
16
18
|
| StackActionType
|
|
19
|
+
| ReturnType<typeof CommonActions.goBack>
|
|
17
20
|
| {
|
|
18
21
|
type: "SNAP_TO";
|
|
19
22
|
index: number;
|
|
20
23
|
source?: string;
|
|
21
24
|
target?: string;
|
|
25
|
+
}
|
|
26
|
+
| {
|
|
27
|
+
type: "DISMISS";
|
|
28
|
+
source?: string;
|
|
29
|
+
target?: string;
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
type: "REMOVE";
|
|
33
|
+
source?: string;
|
|
34
|
+
target?: string;
|
|
22
35
|
};
|
|
23
36
|
|
|
24
37
|
export const BottomSheetActions = {
|
|
25
38
|
...StackActions,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Snap the bottom sheet to a specific index.
|
|
41
|
+
*/
|
|
42
|
+
snapTo: (index: number): BottomSheetActionType => ({ type: "SNAP_TO", index }),
|
|
43
|
+
/**
|
|
44
|
+
* Dismiss the current bottom sheet.
|
|
45
|
+
*/
|
|
46
|
+
dismiss: (): BottomSheetActionType => ({ type: "DISMISS" }),
|
|
47
|
+
/**
|
|
48
|
+
* Remove the sheet from navigation state after dismiss animation completes.
|
|
49
|
+
*/
|
|
50
|
+
remove: (): BottomSheetActionType => ({ type: "REMOVE" }),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Ensures the base route (first screen) exists in the navigation state.
|
|
55
|
+
* This is important because the first screen is the main content,
|
|
56
|
+
* and subsequent screens are rendered as bottom sheets.
|
|
57
|
+
*/
|
|
58
|
+
const ensureBaseRoute = <T extends { routes: { name: string }[] }>(
|
|
59
|
+
state: T,
|
|
60
|
+
baseRouteName: string | undefined,
|
|
61
|
+
routeParamList: Record<string, object | undefined> | undefined,
|
|
62
|
+
): T & { index: number; routes: T["routes"] } => {
|
|
63
|
+
if (!baseRouteName) {
|
|
64
|
+
return state as T & { index: number; routes: T["routes"] };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const hasBaseRoute = state.routes.some((r) => r.name === baseRouteName);
|
|
68
|
+
|
|
69
|
+
if (!hasBaseRoute) {
|
|
70
|
+
const baseRoute = {
|
|
71
|
+
key: `${baseRouteName}-${nanoid()}`,
|
|
72
|
+
name: baseRouteName,
|
|
73
|
+
params: routeParamList?.[baseRouteName],
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
...state,
|
|
78
|
+
index: state.routes.length,
|
|
79
|
+
routes: [baseRoute, ...state.routes],
|
|
80
|
+
} as T & { index: number; routes: T["routes"] };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return state as T & { index: number; routes: T["routes"] };
|
|
29
84
|
};
|
|
30
85
|
|
|
31
|
-
export
|
|
86
|
+
export const BottomSheetRouter = (
|
|
32
87
|
routerOptions: StackRouterOptions,
|
|
33
|
-
): Router<BottomSheetNavigationState<ParamListBase>, BottomSheetActionType> {
|
|
88
|
+
): Router<BottomSheetNavigationState<ParamListBase>, BottomSheetActionType> => {
|
|
34
89
|
const baseRouter = StackRouter(routerOptions) as unknown as Router<
|
|
35
90
|
BottomSheetNavigationState<ParamListBase>,
|
|
36
91
|
BottomSheetActionType
|
|
37
92
|
>;
|
|
93
|
+
|
|
38
94
|
return {
|
|
39
95
|
...baseRouter,
|
|
40
96
|
type: "bottom-sheet",
|
|
97
|
+
|
|
41
98
|
getInitialState(options) {
|
|
42
99
|
const state = baseRouter.getInitialState(options);
|
|
100
|
+
const baseRouteName = routerOptions.initialRouteName ?? options.routeNames[0];
|
|
101
|
+
const stateWithBaseRoute = ensureBaseRoute(
|
|
102
|
+
state,
|
|
103
|
+
baseRouteName,
|
|
104
|
+
options.routeParamList,
|
|
105
|
+
);
|
|
43
106
|
|
|
44
107
|
return {
|
|
45
|
-
...
|
|
108
|
+
...stateWithBaseRoute,
|
|
46
109
|
stale: false,
|
|
47
110
|
type: "bottom-sheet",
|
|
48
111
|
key: `bottom-sheet-${nanoid()}`,
|
|
49
112
|
};
|
|
50
113
|
},
|
|
114
|
+
|
|
51
115
|
getStateForAction(state, action, options) {
|
|
52
116
|
switch (action.type) {
|
|
53
117
|
case "SNAP_TO": {
|
|
54
|
-
const
|
|
118
|
+
const routeIndex =
|
|
55
119
|
action.target === state.key && action.source
|
|
56
120
|
? state.routes.findIndex((r) => r.key === action.source)
|
|
57
121
|
: state.index;
|
|
@@ -59,19 +123,93 @@ export function BottomSheetRouter(
|
|
|
59
123
|
return {
|
|
60
124
|
...state,
|
|
61
125
|
routes: state.routes.map((route, i) =>
|
|
62
|
-
i ===
|
|
126
|
+
i === routeIndex
|
|
63
127
|
? {
|
|
64
128
|
...route,
|
|
65
129
|
snapToIndex: action.index,
|
|
130
|
+
snapToKey: (route.snapToKey ?? 0) + 1,
|
|
66
131
|
}
|
|
67
132
|
: route,
|
|
68
133
|
),
|
|
69
134
|
};
|
|
70
135
|
}
|
|
136
|
+
|
|
137
|
+
case "GO_BACK":
|
|
138
|
+
case "DISMISS": {
|
|
139
|
+
return this.getStateForAction(state, StackActions.pop(1), options);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
case "POP": {
|
|
143
|
+
// Only base screen remains - let parent navigator handle it
|
|
144
|
+
if (state.routes.length <= 1) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const count =
|
|
149
|
+
"payload" in action && typeof action.payload?.count === "number"
|
|
150
|
+
? action.payload.count
|
|
151
|
+
: 1;
|
|
152
|
+
|
|
153
|
+
// Calculate how many routes we can actually pop (don't pop base screen)
|
|
154
|
+
const maxPopCount = state.routes.length - 1;
|
|
155
|
+
const actualCount = Math.min(count, maxPopCount);
|
|
156
|
+
|
|
157
|
+
// Base screen - let parent navigator handle it
|
|
158
|
+
if (actualCount <= 0) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Target index is the route we want to stay on (land on after pop)
|
|
163
|
+
// closingIndex is the first route to be dismissed (the one after target)
|
|
164
|
+
const targetIndex = state.routes.length - 1 - actualCount;
|
|
165
|
+
const closingIndex = targetIndex + 1;
|
|
166
|
+
|
|
167
|
+
// Mark only the bottom-most route to pop as closing
|
|
168
|
+
// The sheet's dismiss() will handle dismissing sheets above it first
|
|
169
|
+
return {
|
|
170
|
+
...state,
|
|
171
|
+
index: closingIndex,
|
|
172
|
+
routes: state.routes.map((route, i) =>
|
|
173
|
+
i === closingIndex ? { ...route, closing: true } : route,
|
|
174
|
+
),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
case "POP_TO_TOP": {
|
|
179
|
+
const popCount = state.routes.length - 1;
|
|
180
|
+
return this.getStateForAction(
|
|
181
|
+
state,
|
|
182
|
+
StackActions.pop(popCount),
|
|
183
|
+
options,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
case "REMOVE": {
|
|
188
|
+
// Actually remove the closing route and all routes above it
|
|
189
|
+
const routeKey = action.source;
|
|
190
|
+
const routeIndex = routeKey
|
|
191
|
+
? state.routes.findIndex((r) => r.key === routeKey)
|
|
192
|
+
: state.routes.findIndex((r) => r.closing);
|
|
193
|
+
|
|
194
|
+
if (routeIndex === -1) {
|
|
195
|
+
return state;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Remove the route and all routes above it (they were dismissed together)
|
|
199
|
+
const routes = state.routes.filter((_, i) => i < routeIndex);
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
...state,
|
|
203
|
+
index: Math.min(state.index, routes.length - 1),
|
|
204
|
+
routes,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
71
208
|
default:
|
|
72
209
|
return baseRouter.getStateForAction(state, action, options);
|
|
73
210
|
}
|
|
74
211
|
},
|
|
212
|
+
|
|
75
213
|
getRehydratedState(partialState, { routeNames, routeParamList, routeGetIdList }) {
|
|
76
214
|
if (partialState.stale === false) {
|
|
77
215
|
return partialState;
|
|
@@ -83,12 +221,43 @@ export function BottomSheetRouter(
|
|
|
83
221
|
routeGetIdList,
|
|
84
222
|
});
|
|
85
223
|
|
|
224
|
+
const baseRouteName = routerOptions.initialRouteName ?? routeNames[0];
|
|
225
|
+
const stateWithBaseRoute = ensureBaseRoute(
|
|
226
|
+
state,
|
|
227
|
+
baseRouteName,
|
|
228
|
+
routeParamList,
|
|
229
|
+
);
|
|
230
|
+
|
|
86
231
|
return {
|
|
87
|
-
...
|
|
232
|
+
...stateWithBaseRoute,
|
|
88
233
|
type: "bottom-sheet",
|
|
89
234
|
key: `bottom-sheet-${nanoid()}`,
|
|
90
235
|
};
|
|
91
236
|
},
|
|
237
|
+
|
|
92
238
|
actionCreators: BottomSheetActions,
|
|
93
239
|
};
|
|
94
|
-
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Hook to access BottomSheet navigation with the snapTo helper.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```tsx
|
|
247
|
+
* function MySheet() {
|
|
248
|
+
* const navigation = useBottomSheetNavigation();
|
|
249
|
+
*
|
|
250
|
+
* // Snap to a specific index
|
|
251
|
+
* const handleExpand = () => {
|
|
252
|
+
* navigation.snapTo(1); // Snap to second index
|
|
253
|
+
* };
|
|
254
|
+
*
|
|
255
|
+
* return (
|
|
256
|
+
* <Button title="Expand" onPress={handleExpand} />
|
|
257
|
+
* );
|
|
258
|
+
* }
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
export const useBottomSheetNavigation = <
|
|
262
|
+
T extends ParamListBase = ParamListBase,
|
|
263
|
+
>(): BottomSheetNavigationProp<T> => useNavigation<BottomSheetNavigationProp<T>>();
|
package/src/router/types.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { BottomSheetModalProps } from "@gorhom/bottom-sheet";
|
|
2
1
|
import type {
|
|
3
2
|
DefaultNavigatorOptions,
|
|
4
3
|
Descriptor,
|
|
@@ -9,28 +8,72 @@ import type {
|
|
|
9
8
|
RouteProp,
|
|
10
9
|
StackActionHelpers,
|
|
11
10
|
} from "@react-navigation/native";
|
|
11
|
+
import type { BottomSheetModalProps } from "@gorhom/bottom-sheet";
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Navigation events emitted by the bottom sheet navigator.
|
|
15
|
+
*/
|
|
16
|
+
export type BottomSheetNavigationEventMap = {
|
|
17
|
+
/**
|
|
18
|
+
* Event emitted when a sheet is presented.
|
|
19
|
+
*/
|
|
20
|
+
sheetPresent: { data: undefined };
|
|
21
|
+
/**
|
|
22
|
+
* Event emitted when a sheet is dismissed.
|
|
23
|
+
*/
|
|
24
|
+
sheetDismiss: { data: undefined };
|
|
25
|
+
};
|
|
15
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Extended route type with bottom sheet specific properties.
|
|
29
|
+
*/
|
|
30
|
+
export type BottomSheetRoute<ParamList extends ParamListBase = ParamListBase> =
|
|
31
|
+
NavigationState<ParamList>["routes"][number] & {
|
|
32
|
+
/**
|
|
33
|
+
* The snap point index the sheet should animate to.
|
|
34
|
+
*/
|
|
35
|
+
snapToIndex?: number | null;
|
|
36
|
+
/**
|
|
37
|
+
* Key to track snap changes for re-rendering.
|
|
38
|
+
*/
|
|
39
|
+
snapToKey?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Whether this route is in the process of being closed.
|
|
42
|
+
*/
|
|
43
|
+
closing?: boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Navigation state type for the bottom sheet navigator.
|
|
48
|
+
*/
|
|
16
49
|
export type BottomSheetNavigationState<ParamList extends ParamListBase> = Omit<
|
|
17
50
|
NavigationState<ParamList>,
|
|
18
|
-
"routes"
|
|
51
|
+
"routes" | "type"
|
|
19
52
|
> & {
|
|
20
53
|
type: "bottom-sheet";
|
|
21
|
-
routes:
|
|
22
|
-
snapToIndex?: number | null;
|
|
23
|
-
})[];
|
|
54
|
+
routes: BottomSheetRoute<ParamList>[];
|
|
24
55
|
};
|
|
25
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Action helpers available on the navigation object.
|
|
59
|
+
*/
|
|
26
60
|
export type BottomSheetActionHelpers<ParamList extends ParamListBase> =
|
|
27
61
|
StackActionHelpers<ParamList> & {
|
|
28
62
|
/**
|
|
29
|
-
* Snap the
|
|
63
|
+
* Snap the sheet to a specific point.
|
|
64
|
+
* @param index The snap point index to snap to.
|
|
30
65
|
*/
|
|
31
|
-
snapTo(index
|
|
66
|
+
snapTo(index: number): void;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Dismiss the current sheet.
|
|
70
|
+
*/
|
|
71
|
+
dismiss(): void;
|
|
32
72
|
};
|
|
33
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Navigation prop type for screens in the bottom sheet navigator.
|
|
76
|
+
*/
|
|
34
77
|
export type BottomSheetNavigationProp<
|
|
35
78
|
ParamList extends ParamListBase,
|
|
36
79
|
RouteName extends keyof ParamList = string,
|
|
@@ -45,6 +88,9 @@ export type BottomSheetNavigationProp<
|
|
|
45
88
|
> &
|
|
46
89
|
BottomSheetActionHelpers<ParamList>;
|
|
47
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Props available to screen components in the bottom sheet navigator.
|
|
93
|
+
*/
|
|
48
94
|
export type BottomSheetScreenProps<
|
|
49
95
|
ParamList extends ParamListBase,
|
|
50
96
|
RouteName extends keyof ParamList = string,
|
|
@@ -54,25 +100,37 @@ export type BottomSheetScreenProps<
|
|
|
54
100
|
route: RouteProp<ParamList, RouteName>;
|
|
55
101
|
};
|
|
56
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Navigation helpers type for the bottom sheet navigator.
|
|
105
|
+
*/
|
|
57
106
|
export type BottomSheetNavigationHelpers = NavigationHelpers<
|
|
58
107
|
ParamListBase,
|
|
59
108
|
BottomSheetNavigationEventMap
|
|
60
|
-
|
|
109
|
+
> &
|
|
110
|
+
BottomSheetActionHelpers<ParamListBase>;
|
|
61
111
|
|
|
62
|
-
|
|
63
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Configuration options for the bottom sheet navigator.
|
|
114
|
+
*/
|
|
115
|
+
export type BottomSheetNavigationConfig = {
|
|
116
|
+
/**
|
|
117
|
+
* Whether to detach inactive sheets from the view hierarchy.
|
|
118
|
+
* @default false
|
|
119
|
+
*/
|
|
120
|
+
detachInactiveScreens?: boolean;
|
|
121
|
+
};
|
|
64
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Screen options available for bottom sheet screens.
|
|
125
|
+
*/
|
|
65
126
|
export type BottomSheetNavigationOptions = Omit<
|
|
66
127
|
BottomSheetModalProps,
|
|
67
|
-
// Remove
|
|
128
|
+
// Remove props that are managed by the navigator
|
|
68
129
|
| "containerHeight"
|
|
69
130
|
| "snapPoints"
|
|
70
131
|
| "gestureEventsHandlersHook"
|
|
71
132
|
| "animatedPosition"
|
|
72
|
-
| "animatedIndex"
|
|
73
|
-
| "topInset"
|
|
74
133
|
| "onChange"
|
|
75
|
-
| "onAnimate"
|
|
76
134
|
| "onClose"
|
|
77
135
|
| "children"
|
|
78
136
|
| "$modal"
|
|
@@ -80,22 +138,55 @@ export type BottomSheetNavigationOptions = Omit<
|
|
|
80
138
|
| "simultaneousHandlers"
|
|
81
139
|
> & {
|
|
82
140
|
/**
|
|
83
|
-
* Points for the bottom sheet to snap to.
|
|
84
|
-
*
|
|
141
|
+
* Points for the bottom sheet to snap to.
|
|
142
|
+
* Accepts an array of numbers (pixels) or strings (percentages).
|
|
143
|
+
*
|
|
85
144
|
* @example
|
|
86
145
|
* snapPoints={[200, 500]}
|
|
87
|
-
* snapPoints={[200, '%
|
|
88
|
-
* snapPoints={['%
|
|
89
|
-
*
|
|
146
|
+
* snapPoints={[200, '50%']}
|
|
147
|
+
* snapPoints={['100%']}
|
|
148
|
+
*
|
|
149
|
+
* @default ['66%']
|
|
90
150
|
*/
|
|
91
151
|
snapPoints?: Array<string | number>;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* When `true`, tapping on the backdrop will not dismiss the sheet.
|
|
155
|
+
* @default false
|
|
156
|
+
*/
|
|
157
|
+
clickThrough?: boolean;
|
|
158
|
+
|
|
92
159
|
/**
|
|
93
|
-
*
|
|
160
|
+
* Whether the bottom sheet is an iOS 18 modal sheet type of animation.
|
|
161
|
+
* When enabled at snap point 90%, the content behind the sheet scales down and gets a
|
|
162
|
+
* border radius, similar to iOS 18 system sheets.
|
|
94
163
|
* @default false
|
|
95
164
|
*/
|
|
165
|
+
iosModalSheetTypeOfAnimation?: boolean;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Opacity of the backdrop overlay.
|
|
169
|
+
* @default 0.45
|
|
170
|
+
*/
|
|
171
|
+
opacity?: number;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export type BottomSheetModalScreenProps = Omit<BottomSheetModalProps, "onDismiss"> & {
|
|
175
|
+
route: BottomSheetRoute;
|
|
176
|
+
navigation: BottomSheetNavigationHelpers;
|
|
177
|
+
|
|
96
178
|
clickThrough?: boolean;
|
|
179
|
+
opacity?: number;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Callback when sheet animation changes.
|
|
183
|
+
*/
|
|
184
|
+
onSheetAnimate?: (from: number, to: number) => void;
|
|
97
185
|
};
|
|
98
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Props for the bottom sheet navigator component.
|
|
189
|
+
*/
|
|
99
190
|
export type BottomSheetNavigatorProps = DefaultNavigatorOptions<
|
|
100
191
|
ParamListBase,
|
|
101
192
|
undefined, // or your ID if you want a named ID, e.g. 'BottomSheetNavigator'
|
|
@@ -106,12 +197,18 @@ export type BottomSheetNavigatorProps = DefaultNavigatorOptions<
|
|
|
106
197
|
> &
|
|
107
198
|
BottomSheetNavigationConfig;
|
|
108
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Descriptor type for bottom sheet screens.
|
|
202
|
+
*/
|
|
109
203
|
export type BottomSheetDescriptor = Descriptor<
|
|
110
204
|
BottomSheetNavigationOptions,
|
|
111
205
|
BottomSheetNavigationProp<ParamListBase>,
|
|
112
206
|
RouteProp<ParamListBase>
|
|
113
207
|
>;
|
|
114
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Map of route keys to their descriptors.
|
|
211
|
+
*/
|
|
115
212
|
export type BottomSheetDescriptorMap = {
|
|
116
213
|
[key: string]: BottomSheetDescriptor;
|
|
117
214
|
};
|