@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.
- package/README.md +414 -69
- package/lib/commonjs/events.js +100 -15
- package/lib/commonjs/events.js.map +1 -1
- package/lib/commonjs/index.js +14 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/manager.js +153 -35
- package/lib/commonjs/manager.js.map +1 -1
- package/lib/commonjs/provider.js +92 -54
- package/lib/commonjs/provider.js.map +1 -1
- package/lib/commonjs/router/index.js +80 -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 +93 -126
- package/lib/commonjs/router/view.js.map +1 -1
- package/lib/commonjs/sheet.js +122 -98
- 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 +2 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/manager.js +154 -35
- package/lib/module/manager.js.map +1 -1
- package/lib/module/provider.js +87 -50
- package/lib/module/provider.js.map +1 -1
- package/lib/module/router/index.js +66 -19
- 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 +92 -126
- package/lib/module/router/view.js.map +1 -1
- package/lib/module/sheet.js +124 -100
- 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 +2 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/manager.d.ts +73 -7
- package/lib/typescript/manager.d.ts.map +1 -1
- package/lib/typescript/provider.d.ts +22 -16
- package/lib/typescript/provider.d.ts.map +1 -1
- package/lib/typescript/router/index.d.ts +47 -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 +142 -32
- package/lib/typescript/router/types.d.ts.map +1 -1
- package/lib/typescript/router/view.d.ts +3 -3
- package/lib/typescript/router/view.d.ts.map +1 -1
- package/lib/typescript/sheet.d.ts +1 -1
- package/lib/typescript/sheet.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +52 -21
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +14 -15
- package/src/events.ts +118 -27
- package/src/index.ts +2 -1
- package/src/manager.ts +209 -42
- package/src/provider.tsx +144 -71
- package/src/router/index.tsx +77 -33
- package/src/router/router.ts +188 -15
- package/src/router/types.ts +172 -57
- package/src/router/view.tsx +111 -213
- package/src/sheet.tsx +192 -124
- package/src/types.ts +51 -24
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
-
import { createNavigatorFactory, useNavigationBuilder } from "@react-navigation/native";
|
|
3
|
-
import React from "react";
|
|
2
|
+
import { createNavigatorFactory, StackActions, useNavigationBuilder } from "@react-navigation/native";
|
|
3
|
+
import * as React from "react";
|
|
4
4
|
import { BottomSheetRouter } from "./router";
|
|
5
5
|
import { BottomSheetView } from "./view";
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Unified Navigator that renders the first screen as the base content
|
|
9
|
+
* and all subsequent screens as bottom sheet overlays.
|
|
10
|
+
*
|
|
11
|
+
* Uses BottomSheetRouter (extending StackRouter) to manage navigation state,
|
|
12
|
+
* with react-native-screens ScreenStack for the base screen rendering
|
|
13
|
+
* and BottomSheetView for the sheet overlays.
|
|
14
|
+
*/
|
|
15
|
+
function Navigator({
|
|
7
16
|
id,
|
|
8
17
|
children,
|
|
9
18
|
screenListeners,
|
|
10
19
|
screenOptions,
|
|
20
|
+
initialRouteName,
|
|
11
21
|
...rest
|
|
12
22
|
}) {
|
|
13
23
|
const {
|
|
@@ -19,8 +29,25 @@ function BottomSheetNavigator({
|
|
|
19
29
|
id,
|
|
20
30
|
children,
|
|
21
31
|
screenListeners,
|
|
22
|
-
screenOptions
|
|
32
|
+
screenOptions,
|
|
33
|
+
initialRouteName
|
|
23
34
|
});
|
|
35
|
+
|
|
36
|
+
// Handle tab press → popToTop behavior
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
// @ts-expect-error: there may not be a tab navigator in parent
|
|
39
|
+
return navigation?.addListener?.("tabPress", e => {
|
|
40
|
+
const isFocused = navigation.isFocused();
|
|
41
|
+
requestAnimationFrame(() => {
|
|
42
|
+
if (state.index > 0 && isFocused && !e.defaultPrevented) {
|
|
43
|
+
navigation.dispatch({
|
|
44
|
+
...StackActions.popToTop(),
|
|
45
|
+
target: state.key
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}, [navigation, state.index, state.key]);
|
|
24
51
|
return /*#__PURE__*/React.createElement(NavigationContent, null, /*#__PURE__*/React.createElement(BottomSheetView, _extends({}, rest, {
|
|
25
52
|
state: state,
|
|
26
53
|
navigation: navigation,
|
|
@@ -29,18 +56,38 @@ function BottomSheetNavigator({
|
|
|
29
56
|
}
|
|
30
57
|
|
|
31
58
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
59
|
+
* Creates a bottom sheet navigator that renders the first screen as the
|
|
60
|
+
* main content and all subsequent screens as bottom sheet modals.
|
|
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
|
+
* ```
|
|
34
80
|
*
|
|
35
81
|
* @example
|
|
36
82
|
* ```tsx
|
|
83
|
+
* // With Expo Router
|
|
84
|
+
* import { Slot, withLayoutContext } from "expo-router";
|
|
37
85
|
* import {
|
|
38
86
|
* createBottomSheetNavigator,
|
|
39
87
|
* BottomSheetNavigationOptions,
|
|
40
88
|
* BottomSheetNavigationEventMap,
|
|
41
89
|
* BottomSheetNavigationState,
|
|
42
|
-
* } from "@
|
|
43
|
-
* import { Slot, withLayoutContext } from "expo-router";
|
|
90
|
+
* } from "@niibase/bottom-sheet-manager";
|
|
44
91
|
*
|
|
45
92
|
* const { Navigator } = createBottomSheetNavigator();
|
|
46
93
|
*
|
|
@@ -56,24 +103,24 @@ function BottomSheetNavigator({
|
|
|
56
103
|
* };
|
|
57
104
|
*
|
|
58
105
|
* export default function Layout() {
|
|
106
|
+
* // SSR guard - navigator doesn't work on server
|
|
59
107
|
* if (typeof window === "undefined") return <Slot />;
|
|
108
|
+
*
|
|
60
109
|
* return (
|
|
61
|
-
* <BottomSheet
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*. />
|
|
110
|
+
* <BottomSheet>
|
|
111
|
+
* <BottomSheet.Screen name="index" />
|
|
112
|
+
* <BottomSheet.Screen
|
|
113
|
+
* name="details"
|
|
114
|
+
* options={{ snapPoints: ["50%"] }}
|
|
115
|
+
* />
|
|
116
|
+
* </BottomSheet>
|
|
69
117
|
* );
|
|
70
118
|
* }
|
|
71
119
|
* ```
|
|
72
120
|
*/
|
|
73
121
|
export function createBottomSheetNavigator(config) {
|
|
74
|
-
|
|
75
|
-
// but pass in the config to get the typed container
|
|
76
|
-
return createNavigatorFactory(BottomSheetNavigator)(config);
|
|
122
|
+
return createNavigatorFactory(Navigator)(config);
|
|
77
123
|
}
|
|
78
124
|
export * from "./types";
|
|
125
|
+
export { BottomSheetActions, useBottomSheetNavigation } from "./router";
|
|
79
126
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createNavigatorFactory","useNavigationBuilder","React","BottomSheetRouter","BottomSheetView","
|
|
1
|
+
{"version":3,"names":["createNavigatorFactory","StackActions","useNavigationBuilder","React","BottomSheetRouter","BottomSheetView","Navigator","id","children","screenListeners","screenOptions","initialRouteName","rest","state","descriptors","navigation","NavigationContent","useEffect","addListener","e","isFocused","requestAnimationFrame","index","defaultPrevented","dispatch","popToTop","target","key","createElement","_extends","createBottomSheetNavigator","config","BottomSheetActions","useBottomSheetNavigation"],"sourceRoot":"../../../src","sources":["router/index.tsx"],"mappings":";AAAA,SACEA,sBAAsB,EAEtBC,YAAY,EACZC,oBAAoB,QAKf,0BAA0B;AACjC,OAAO,KAAKC,KAAK,MAAM,OAAO;AAU9B,SAASC,iBAAiB,QAAuC,UAAU;AAC3E,SAASC,eAAe,QAAQ,QAAQ;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,SAASA,CAAC;EACjBC,EAAE;EACFC,QAAQ;EACRC,eAAe;EACfC,aAAa;EACbC,gBAAgB;EAChB,GAAGC;AACsB,CAAC,EAAE;EAC5B,MAAM;IAAEC,KAAK;IAAEC,WAAW;IAAEC,UAAU;IAAEC;EAAkB,CAAC,GAAGd,oBAAoB,CAMhFE,iBAAiB,EAAE;IACnBG,EAAE;IACFC,QAAQ;IACRC,eAAe;IACfC,aAAa;IACbC;EACF,CAAC,CAAC;;EAEF;EACAR,KAAK,CAACc,SAAS,CAAC,MAAM;IACpB;IACA,OAAOF,UAAU,EAAEG,WAAW,GAAG,UAAU,EAAGC,CAAM,IAAK;MACvD,MAAMC,SAAS,GAAGL,UAAU,CAACK,SAAS,CAAC,CAAC;MAExCC,qBAAqB,CAAC,MAAM;QAC1B,IACER,KAAK,CAACS,KAAK,GAAG,CAAC,IACfF,SAAS,IACT,CAAED,CAAC,CAAgCI,gBAAgB,EACnD;UACAR,UAAU,CAACS,QAAQ,CAAC;YAClB,GAAGvB,YAAY,CAACwB,QAAQ,CAAC,CAAC;YAC1BC,MAAM,EAAEb,KAAK,CAACc;UAChB,CAAC,CAAC;QACJ;MACF,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ,CAAC,EAAE,CAACZ,UAAU,EAAEF,KAAK,CAACS,KAAK,EAAET,KAAK,CAACc,GAAG,CAAC,CAAC;EAExC,oBACExB,KAAA,CAAAyB,aAAA,CAACZ,iBAAiB,qBAChBb,KAAA,CAAAyB,aAAA,CAACvB,eAAe,EAAAwB,QAAA,KACVjB,IAAI;IACRC,KAAK,EAAEA,KAAM;IACbE,UAAU,EAAEA,UAAW;IACvBD,WAAW,EAAEA;EAAY,EAC1B,CACgB,CAAC;AAExB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASgB,0BAA0BA,CAmBxCC,MAAe,EAAmC;EAClD,OAAO/B,sBAAsB,CAACM,SAAS,CAAC,CAACyB,MAAM,CAAC;AAClD;AAEA,cAAc,SAAS;AACvB,SAASC,kBAAkB,EAAEC,wBAAwB,QAAQ,UAAU","ignoreList":[]}
|
|
@@ -1,23 +1,63 @@
|
|
|
1
|
-
import { StackActions, StackRouter } from "@react-navigation/native";
|
|
1
|
+
import { StackActions, StackRouter, useNavigation } from "@react-navigation/native";
|
|
2
2
|
import { nanoid } from "nanoid/non-secure";
|
|
3
3
|
export const BottomSheetActions = {
|
|
4
4
|
...StackActions,
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Snap the bottom sheet to a specific index.
|
|
7
|
+
*/
|
|
8
|
+
snapTo: index => ({
|
|
9
|
+
type: "SNAP_TO",
|
|
10
|
+
index
|
|
11
|
+
}),
|
|
12
|
+
/**
|
|
13
|
+
* Dismiss the current bottom sheet.
|
|
14
|
+
*/
|
|
15
|
+
dismiss: () => ({
|
|
16
|
+
type: "DISMISS"
|
|
17
|
+
}),
|
|
18
|
+
/**
|
|
19
|
+
* Remove the sheet from navigation state after dismiss animation completes.
|
|
20
|
+
*/
|
|
21
|
+
remove: () => ({
|
|
22
|
+
type: "REMOVE"
|
|
23
|
+
})
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Ensures the base route (first screen) exists in the navigation state.
|
|
28
|
+
* This is important because the first screen is the main content,
|
|
29
|
+
* and subsequent screens are rendered as bottom sheets.
|
|
30
|
+
*/
|
|
31
|
+
const ensureBaseRoute = (state, baseRouteName, routeParamList) => {
|
|
32
|
+
if (!baseRouteName) {
|
|
33
|
+
return state;
|
|
34
|
+
}
|
|
35
|
+
const hasBaseRoute = state.routes.some(r => r.name === baseRouteName);
|
|
36
|
+
if (!hasBaseRoute) {
|
|
37
|
+
const baseRoute = {
|
|
38
|
+
key: `${baseRouteName}-${nanoid()}`,
|
|
39
|
+
name: baseRouteName,
|
|
40
|
+
params: routeParamList?.[baseRouteName]
|
|
41
|
+
};
|
|
6
42
|
return {
|
|
7
|
-
|
|
8
|
-
index
|
|
43
|
+
...state,
|
|
44
|
+
index: state.routes.length,
|
|
45
|
+
routes: [baseRoute, ...state.routes]
|
|
9
46
|
};
|
|
10
47
|
}
|
|
48
|
+
return state;
|
|
11
49
|
};
|
|
12
|
-
export
|
|
50
|
+
export const BottomSheetRouter = routerOptions => {
|
|
13
51
|
const baseRouter = StackRouter(routerOptions);
|
|
14
52
|
return {
|
|
15
53
|
...baseRouter,
|
|
16
54
|
type: "bottom-sheet",
|
|
17
55
|
getInitialState(options) {
|
|
18
56
|
const state = baseRouter.getInitialState(options);
|
|
57
|
+
const baseRouteName = routerOptions.initialRouteName ?? options.routeNames[0];
|
|
58
|
+
const stateWithBaseRoute = ensureBaseRoute(state, baseRouteName, options.routeParamList);
|
|
19
59
|
return {
|
|
20
|
-
...
|
|
60
|
+
...stateWithBaseRoute,
|
|
21
61
|
stale: false,
|
|
22
62
|
type: "bottom-sheet",
|
|
23
63
|
key: `bottom-sheet-${nanoid()}`
|
|
@@ -27,15 +67,76 @@ export function BottomSheetRouter(routerOptions) {
|
|
|
27
67
|
switch (action.type) {
|
|
28
68
|
case "SNAP_TO":
|
|
29
69
|
{
|
|
30
|
-
const
|
|
70
|
+
const routeIndex = action.target === state.key && action.source ? state.routes.findIndex(r => r.key === action.source) : state.index;
|
|
71
|
+
return {
|
|
72
|
+
...state,
|
|
73
|
+
routes: state.routes.map((route, i) => i === routeIndex ? {
|
|
74
|
+
...route,
|
|
75
|
+
snapToIndex: action.index,
|
|
76
|
+
snapToKey: (route.snapToKey ?? 0) + 1
|
|
77
|
+
} : route)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
case "GO_BACK":
|
|
81
|
+
case "DISMISS":
|
|
82
|
+
{
|
|
83
|
+
return this.getStateForAction(state, StackActions.pop(1), options);
|
|
84
|
+
}
|
|
85
|
+
case "POP":
|
|
86
|
+
{
|
|
87
|
+
// Only base screen remains - let parent navigator handle it
|
|
88
|
+
if (state.routes.length <= 1) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const count = "payload" in action && typeof action.payload?.count === "number" ? action.payload.count : 1;
|
|
92
|
+
|
|
93
|
+
// Calculate how many routes we can actually pop (don't pop base screen)
|
|
94
|
+
const maxPopCount = state.routes.length - 1;
|
|
95
|
+
const actualCount = Math.min(count, maxPopCount);
|
|
96
|
+
|
|
97
|
+
// Base screen - let parent navigator handle it
|
|
98
|
+
if (actualCount <= 0) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Target index is the route we want to stay on (land on after pop)
|
|
103
|
+
// closingIndex is the first route to be dismissed (the one after target)
|
|
104
|
+
const targetIndex = state.routes.length - 1 - actualCount;
|
|
105
|
+
const closingIndex = targetIndex + 1;
|
|
106
|
+
|
|
107
|
+
// Mark only the bottom-most route to pop as closing
|
|
108
|
+
// The sheet's dismiss() will handle dismissing sheets above it first
|
|
31
109
|
return {
|
|
32
110
|
...state,
|
|
33
|
-
|
|
111
|
+
index: closingIndex,
|
|
112
|
+
routes: state.routes.map((route, i) => i === closingIndex ? {
|
|
34
113
|
...route,
|
|
35
|
-
|
|
114
|
+
closing: true
|
|
36
115
|
} : route)
|
|
37
116
|
};
|
|
38
117
|
}
|
|
118
|
+
case "POP_TO_TOP":
|
|
119
|
+
{
|
|
120
|
+
const popCount = state.routes.length - 1;
|
|
121
|
+
return this.getStateForAction(state, StackActions.pop(popCount), options);
|
|
122
|
+
}
|
|
123
|
+
case "REMOVE":
|
|
124
|
+
{
|
|
125
|
+
// Actually remove the closing route and all routes above it
|
|
126
|
+
const routeKey = action.source;
|
|
127
|
+
const routeIndex = routeKey ? state.routes.findIndex(r => r.key === routeKey) : state.routes.findIndex(r => r.closing);
|
|
128
|
+
if (routeIndex === -1) {
|
|
129
|
+
return state;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Remove the route and all routes above it (they were dismissed together)
|
|
133
|
+
const routes = state.routes.filter((_, i) => i < routeIndex);
|
|
134
|
+
return {
|
|
135
|
+
...state,
|
|
136
|
+
index: Math.min(state.index, routes.length - 1),
|
|
137
|
+
routes
|
|
138
|
+
};
|
|
139
|
+
}
|
|
39
140
|
default:
|
|
40
141
|
return baseRouter.getStateForAction(state, action, options);
|
|
41
142
|
}
|
|
@@ -53,13 +154,36 @@ export function BottomSheetRouter(routerOptions) {
|
|
|
53
154
|
routeParamList,
|
|
54
155
|
routeGetIdList
|
|
55
156
|
});
|
|
157
|
+
const baseRouteName = routerOptions.initialRouteName ?? routeNames[0];
|
|
158
|
+
const stateWithBaseRoute = ensureBaseRoute(state, baseRouteName, routeParamList);
|
|
56
159
|
return {
|
|
57
|
-
...
|
|
160
|
+
...stateWithBaseRoute,
|
|
58
161
|
type: "bottom-sheet",
|
|
59
162
|
key: `bottom-sheet-${nanoid()}`
|
|
60
163
|
};
|
|
61
164
|
},
|
|
62
165
|
actionCreators: BottomSheetActions
|
|
63
166
|
};
|
|
64
|
-
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Hook to access BottomSheet navigation with the snapTo helper.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```tsx
|
|
174
|
+
* function MySheet() {
|
|
175
|
+
* const navigation = useBottomSheetNavigation();
|
|
176
|
+
*
|
|
177
|
+
* // Snap to a specific index
|
|
178
|
+
* const handleExpand = () => {
|
|
179
|
+
* navigation.snapTo(1); // Snap to second index
|
|
180
|
+
* };
|
|
181
|
+
*
|
|
182
|
+
* return (
|
|
183
|
+
* <Button title="Expand" onPress={handleExpand} />
|
|
184
|
+
* );
|
|
185
|
+
* }
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
export const useBottomSheetNavigation = () => useNavigation();
|
|
65
189
|
//# sourceMappingURL=router.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["StackActions","StackRouter","nanoid","BottomSheetActions","snapTo","index","type","BottomSheetRouter","routerOptions","baseRouter","getInitialState","options","
|
|
1
|
+
{"version":3,"names":["StackActions","StackRouter","useNavigation","nanoid","BottomSheetActions","snapTo","index","type","dismiss","remove","ensureBaseRoute","state","baseRouteName","routeParamList","hasBaseRoute","routes","some","r","name","baseRoute","key","params","length","BottomSheetRouter","routerOptions","baseRouter","getInitialState","options","initialRouteName","routeNames","stateWithBaseRoute","stale","getStateForAction","action","routeIndex","target","source","findIndex","map","route","i","snapToIndex","snapToKey","pop","count","payload","maxPopCount","actualCount","Math","min","targetIndex","closingIndex","closing","popCount","routeKey","filter","_","getRehydratedState","partialState","routeGetIdList","actionCreators","useBottomSheetNavigation"],"sourceRoot":"../../../src","sources":["router/router.ts"],"mappings":"AAAA,SACIA,YAAY,EACZC,WAAW,EACXC,aAAa,QAMV,0BAA0B;AACjC,SAASC,MAAM,QAAQ,mBAAmB;AA0B1C,OAAO,MAAMC,kBAAkB,GAAG;EAC9B,GAAGJ,YAAY;EACf;AACJ;AACA;EACIK,MAAM,EAAGC,KAAa,KAA6B;IAAEC,IAAI,EAAE,SAAS;IAAED;EAAM,CAAC,CAAC;EAC9E;AACJ;AACA;EACIE,OAAO,EAAEA,CAAA,MAA8B;IAAED,IAAI,EAAE;EAAU,CAAC,CAAC;EAC3D;AACJ;AACA;EACIE,MAAM,EAAEA,CAAA,MAA8B;IAAEF,IAAI,EAAE;EAAS,CAAC;AAC5D,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,MAAMG,eAAe,GAAGA,CACpBC,KAAQ,EACRC,aAAiC,EACjCC,cAA8D,KACjB;EAC7C,IAAI,CAACD,aAAa,EAAE;IAChB,OAAOD,KAAK;EAChB;EAEA,MAAMG,YAAY,GAAGH,KAAK,CAACI,MAAM,CAACC,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,IAAI,KAAKN,aAAa,CAAC;EAEvE,IAAI,CAACE,YAAY,EAAE;IACf,MAAMK,SAAS,GAAG;MACdC,GAAG,EAAE,GAAGR,aAAa,IAAIT,MAAM,CAAC,CAAC,EAAE;MACnCe,IAAI,EAAEN,aAAa;MACnBS,MAAM,EAAER,cAAc,GAAGD,aAAa;IAC1C,CAAC;IAED,OAAO;MACH,GAAGD,KAAK;MACRL,KAAK,EAAEK,KAAK,CAACI,MAAM,CAACO,MAAM;MAC1BP,MAAM,EAAE,CAACI,SAAS,EAAE,GAAGR,KAAK,CAACI,MAAM;IACvC,CAAC;EACL;EAEA,OAAOJ,KAAK;AAChB,CAAC;AAED,OAAO,MAAMY,iBAAiB,GAC1BC,aAAiC,IAIhC;EACD,MAAMC,UAAU,GAAGxB,WAAW,CAACuB,aAAa,CAG3C;EAED,OAAO;IACH,GAAGC,UAAU;IACblB,IAAI,EAAE,cAAc;IAEpBmB,eAAeA,CAACC,OAAO,EAAE;MACrB,MAAMhB,KAAK,GAAGc,UAAU,CAACC,eAAe,CAACC,OAAO,CAAC;MACjD,MAAMf,aAAa,GAAGY,aAAa,CAACI,gBAAgB,IAAID,OAAO,CAACE,UAAU,CAAC,CAAC,CAAC;MAC7E,MAAMC,kBAAkB,GAAGpB,eAAe,CACtCC,KAAK,EACLC,aAAa,EACbe,OAAO,CAACd,cACZ,CAAC;MAED,OAAO;QACH,GAAGiB,kBAAkB;QACrBC,KAAK,EAAE,KAAK;QACZxB,IAAI,EAAE,cAAc;QACpBa,GAAG,EAAE,gBAAgBjB,MAAM,CAAC,CAAC;MACjC,CAAC;IACL,CAAC;IAED6B,iBAAiBA,CAACrB,KAAK,EAAEsB,MAAM,EAAEN,OAAO,EAAE;MACtC,QAAQM,MAAM,CAAC1B,IAAI;QACf,KAAK,SAAS;UAAE;YACZ,MAAM2B,UAAU,GACZD,MAAM,CAACE,MAAM,KAAKxB,KAAK,CAACS,GAAG,IAAIa,MAAM,CAACG,MAAM,GACtCzB,KAAK,CAACI,MAAM,CAACsB,SAAS,CAAEpB,CAAC,IAAKA,CAAC,CAACG,GAAG,KAAKa,MAAM,CAACG,MAAM,CAAC,GACtDzB,KAAK,CAACL,KAAK;YAErB,OAAO;cACH,GAAGK,KAAK;cACRI,MAAM,EAAEJ,KAAK,CAACI,MAAM,CAACuB,GAAG,CAAC,CAACC,KAAK,EAAEC,CAAC,KAC9BA,CAAC,KAAKN,UAAU,GACV;gBACI,GAAGK,KAAK;gBACRE,WAAW,EAAER,MAAM,CAAC3B,KAAK;gBACzBoC,SAAS,EAAE,CAACH,KAAK,CAACG,SAAS,IAAI,CAAC,IAAI;cACxC,CAAC,GACDH,KACV;YACJ,CAAC;UACL;QAEA,KAAK,SAAS;QACd,KAAK,SAAS;UAAE;YACZ,OAAO,IAAI,CAACP,iBAAiB,CAACrB,KAAK,EAAEX,YAAY,CAAC2C,GAAG,CAAC,CAAC,CAAC,EAAEhB,OAAO,CAAC;UACtE;QAEA,KAAK,KAAK;UAAE;YACR;YACA,IAAIhB,KAAK,CAACI,MAAM,CAACO,MAAM,IAAI,CAAC,EAAE;cAC1B,OAAO,IAAI;YACf;YAEA,MAAMsB,KAAK,GACP,SAAS,IAAIX,MAAM,IAAI,OAAOA,MAAM,CAACY,OAAO,EAAED,KAAK,KAAK,QAAQ,GAC1DX,MAAM,CAACY,OAAO,CAACD,KAAK,GACpB,CAAC;;YAEX;YACA,MAAME,WAAW,GAAGnC,KAAK,CAACI,MAAM,CAACO,MAAM,GAAG,CAAC;YAC3C,MAAMyB,WAAW,GAAGC,IAAI,CAACC,GAAG,CAACL,KAAK,EAAEE,WAAW,CAAC;;YAEhD;YACA,IAAIC,WAAW,IAAI,CAAC,EAAE;cAClB,OAAO,IAAI;YACf;;YAEA;YACA;YACA,MAAMG,WAAW,GAAGvC,KAAK,CAACI,MAAM,CAACO,MAAM,GAAG,CAAC,GAAGyB,WAAW;YACzD,MAAMI,YAAY,GAAGD,WAAW,GAAG,CAAC;;YAEpC;YACA;YACA,OAAO;cACH,GAAGvC,KAAK;cACRL,KAAK,EAAE6C,YAAY;cACnBpC,MAAM,EAAEJ,KAAK,CAACI,MAAM,CAACuB,GAAG,CAAC,CAACC,KAAK,EAAEC,CAAC,KAC9BA,CAAC,KAAKW,YAAY,GAAG;gBAAE,GAAGZ,KAAK;gBAAEa,OAAO,EAAE;cAAK,CAAC,GAAGb,KACvD;YACJ,CAAC;UACL;QAEA,KAAK,YAAY;UAAE;YACf,MAAMc,QAAQ,GAAG1C,KAAK,CAACI,MAAM,CAACO,MAAM,GAAG,CAAC;YACxC,OAAO,IAAI,CAACU,iBAAiB,CACzBrB,KAAK,EACLX,YAAY,CAAC2C,GAAG,CAACU,QAAQ,CAAC,EAC1B1B,OACJ,CAAC;UACL;QAEA,KAAK,QAAQ;UAAE;YACX;YACA,MAAM2B,QAAQ,GAAGrB,MAAM,CAACG,MAAM;YAC9B,MAAMF,UAAU,GAAGoB,QAAQ,GACrB3C,KAAK,CAACI,MAAM,CAACsB,SAAS,CAAEpB,CAAC,IAAKA,CAAC,CAACG,GAAG,KAAKkC,QAAQ,CAAC,GACjD3C,KAAK,CAACI,MAAM,CAACsB,SAAS,CAAEpB,CAAC,IAAKA,CAAC,CAACmC,OAAO,CAAC;YAE9C,IAAIlB,UAAU,KAAK,CAAC,CAAC,EAAE;cACnB,OAAOvB,KAAK;YAChB;;YAEA;YACA,MAAMI,MAAM,GAAGJ,KAAK,CAACI,MAAM,CAACwC,MAAM,CAAC,CAACC,CAAC,EAAEhB,CAAC,KAAKA,CAAC,GAAGN,UAAU,CAAC;YAE5D,OAAO;cACH,GAAGvB,KAAK;cACRL,KAAK,EAAE0C,IAAI,CAACC,GAAG,CAACtC,KAAK,CAACL,KAAK,EAAES,MAAM,CAACO,MAAM,GAAG,CAAC,CAAC;cAC/CP;YACJ,CAAC;UACL;QAEA;UACI,OAAOU,UAAU,CAACO,iBAAiB,CAACrB,KAAK,EAAEsB,MAAM,EAAEN,OAAO,CAAC;MACnE;IACJ,CAAC;IAED8B,kBAAkBA,CAACC,YAAY,EAAE;MAAE7B,UAAU;MAAEhB,cAAc;MAAE8C;IAAe,CAAC,EAAE;MAC7E,IAAID,YAAY,CAAC3B,KAAK,KAAK,KAAK,EAAE;QAC9B,OAAO2B,YAAY;MACvB;MAEA,MAAM/C,KAAK,GAAGc,UAAU,CAACgC,kBAAkB,CAACC,YAAY,EAAE;QACtD7B,UAAU;QACVhB,cAAc;QACd8C;MACJ,CAAC,CAAC;MAEF,MAAM/C,aAAa,GAAGY,aAAa,CAACI,gBAAgB,IAAIC,UAAU,CAAC,CAAC,CAAC;MACrE,MAAMC,kBAAkB,GAAGpB,eAAe,CACtCC,KAAK,EACLC,aAAa,EACbC,cACJ,CAAC;MAED,OAAO;QACH,GAAGiB,kBAAkB;QACrBvB,IAAI,EAAE,cAAc;QACpBa,GAAG,EAAE,gBAAgBjB,MAAM,CAAC,CAAC;MACjC,CAAC;IACL,CAAC;IAEDyD,cAAc,EAAExD;EACpB,CAAC;AACL,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMyD,wBAAwB,GAAGA,CAAA,KAGpC3D,aAAa,CAA+B,CAAC","ignoreList":[]}
|
|
@@ -1,173 +1,139 @@
|
|
|
1
1
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
-
import {
|
|
2
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
3
3
|
import { useTheme } from "@react-navigation/native";
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
function BottomSheetModalScreen({
|
|
9
|
-
index,
|
|
10
|
-
navigation,
|
|
11
|
-
clickThrough,
|
|
12
|
-
iosModalSheetTypeOfAnimation,
|
|
13
|
-
opacity,
|
|
5
|
+
import { BottomSheetActions } from "./router";
|
|
6
|
+
import BottomSheet from "../sheet";
|
|
7
|
+
function BottomSheetScreen({
|
|
14
8
|
children,
|
|
9
|
+
navigation,
|
|
10
|
+
route,
|
|
15
11
|
...props
|
|
16
12
|
}) {
|
|
17
13
|
const ref = React.useRef(null);
|
|
18
|
-
const
|
|
14
|
+
const lastSnapIndexRef = React.useRef(route.snapToIndex ?? props.index ?? 0);
|
|
19
15
|
|
|
20
|
-
//
|
|
21
|
-
React.useEffect(() => {
|
|
22
|
-
ref.current?.present();
|
|
23
|
-
}, []);
|
|
24
|
-
const isMounted = React.useRef(true);
|
|
16
|
+
// Handle route closing state
|
|
25
17
|
React.useEffect(() => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
}, []);
|
|
18
|
+
if (route.closing) {
|
|
19
|
+
ref.current?.close();
|
|
20
|
+
}
|
|
21
|
+
}, [route.closing]);
|
|
22
|
+
|
|
23
|
+
// Handle snap point changes from navigation actions
|
|
30
24
|
React.useEffect(() => {
|
|
31
|
-
if (
|
|
32
|
-
ref.current?.snapToIndex(
|
|
25
|
+
if (route.snapToIndex != null && route.snapToIndex !== lastSnapIndexRef.current) {
|
|
26
|
+
ref.current?.snapToIndex(route.snapToIndex);
|
|
27
|
+
lastSnapIndexRef.current = route.snapToIndex;
|
|
33
28
|
}
|
|
34
|
-
}, [
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
}, [route.snapToIndex, route.snapToKey]);
|
|
30
|
+
const handleChange = React.useCallback((newIndex, position, type) => {
|
|
31
|
+
navigation.emit({
|
|
32
|
+
type: "sheetOnChange",
|
|
33
|
+
target: route.key,
|
|
34
|
+
data: {
|
|
35
|
+
index: newIndex,
|
|
36
|
+
position,
|
|
37
|
+
type
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const currentIndex = lastSnapIndexRef.current;
|
|
41
|
+
lastSnapIndexRef.current = newIndex;
|
|
38
42
|
if (newIndex >= 0 && newIndex !== currentIndex) {
|
|
39
|
-
navigation.snapTo(newIndex);
|
|
40
|
-
}
|
|
41
|
-
}, [navigation]);
|
|
42
|
-
const onDismiss = React.useCallback(() => {
|
|
43
|
-
// BottomSheetModal will call onDismiss on unmount, be we do not want that since
|
|
44
|
-
// we already popped the screen.
|
|
45
|
-
if (isMounted.current) {
|
|
46
|
-
navigation.goBack();
|
|
43
|
+
navigation.dispatch(BottomSheetActions.snapTo(newIndex));
|
|
47
44
|
}
|
|
48
45
|
}, [navigation]);
|
|
49
|
-
return /*#__PURE__*/React.createElement(
|
|
46
|
+
return /*#__PURE__*/React.createElement(BottomSheet, _extends({
|
|
50
47
|
ref: ref,
|
|
51
|
-
|
|
52
|
-
onChange: onChange,
|
|
53
|
-
index: index,
|
|
54
|
-
backdropComponent: props => /*#__PURE__*/React.createElement(BottomSheetBackdrop, _extends({}, props, {
|
|
55
|
-
appearsOnIndex: 0,
|
|
56
|
-
disappearsOnIndex: -1,
|
|
57
|
-
enableTouchThrough: !!clickThrough,
|
|
58
|
-
opacity: opacity || 0.45
|
|
59
|
-
}))
|
|
48
|
+
onChange: handleChange
|
|
60
49
|
}, props), children);
|
|
61
50
|
}
|
|
62
|
-
const DEFAULT_SNAP_POINTS = ["66%"];
|
|
63
51
|
export function BottomSheetView({
|
|
64
52
|
state,
|
|
53
|
+
navigation,
|
|
65
54
|
descriptors
|
|
66
55
|
}) {
|
|
67
56
|
const {
|
|
68
57
|
colors
|
|
69
58
|
} = useTheme();
|
|
70
59
|
const {
|
|
71
|
-
|
|
60
|
+
bottom,
|
|
61
|
+
left,
|
|
62
|
+
right
|
|
72
63
|
} = useSafeAreaInsets();
|
|
73
64
|
const themeBackgroundStyle = React.useMemo(() => ({
|
|
65
|
+
borderCurve: "continuous",
|
|
74
66
|
backgroundColor: colors.card
|
|
75
67
|
}), [colors.card]);
|
|
76
68
|
const themeHandleIndicatorStyle = React.useMemo(() => ({
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
width: 50
|
|
69
|
+
borderCurve: "continuous",
|
|
70
|
+
backgroundColor: colors.border
|
|
80
71
|
}), [colors.border]);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
flex: 1,
|
|
90
|
-
transform: [{
|
|
91
|
-
scaleX: withSpring(interpolate(isFullScreen.value, [0, 1], [1, 0.92]), {
|
|
92
|
-
damping: 15,
|
|
93
|
-
stiffness: 100
|
|
94
|
-
})
|
|
95
|
-
}, {
|
|
96
|
-
translateY: withSpring(interpolate(isFullScreen.value, [0, 1], [0, top + 5]), {
|
|
97
|
-
damping: 15,
|
|
98
|
-
stiffness: 100
|
|
99
|
-
})
|
|
100
|
-
}]
|
|
101
|
-
}));
|
|
102
|
-
|
|
103
|
-
// Since background color is white, we need to set status bar to light
|
|
104
|
-
const setStatusBar = StatusBar.setBarStyle;
|
|
105
|
-
useAnimatedReaction(() => isFullScreen.value, currentValue => {
|
|
106
|
-
"worklet";
|
|
107
|
-
|
|
108
|
-
if (currentValue > -1) {
|
|
109
|
-
runOnJS(setStatusBar)(currentValue >= 0.5 ? "light-content" : "default");
|
|
110
|
-
}
|
|
111
|
-
}, []);
|
|
112
|
-
|
|
113
|
-
// Avoid rendering provider if we only have one screen.
|
|
114
|
-
const shouldRenderProvider = React.useRef(false);
|
|
115
|
-
shouldRenderProvider.current = shouldRenderProvider.current || state.routes.length > 1;
|
|
116
|
-
const firstRoute = state.routes[0];
|
|
117
|
-
if (!firstRoute) {
|
|
118
|
-
// no routes at all, probably shouldn't happen, but let's be defensive
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
const firstDescriptor = descriptors[firstRoute.key];
|
|
122
|
-
if (!firstDescriptor) {
|
|
123
|
-
// if we don't have a descriptor for the first route, bail out
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Animated.View, {
|
|
127
|
-
style: colorStyle
|
|
128
|
-
}, /*#__PURE__*/React.createElement(Animated.View, {
|
|
129
|
-
style: animatedStyle
|
|
130
|
-
}, firstDescriptor.render?.())), shouldRenderProvider.current && /*#__PURE__*/React.createElement(BottomSheetModalProvider, null, state.routes.slice(1).map(route => {
|
|
72
|
+
const defaultStyle = React.useMemo(() => ({
|
|
73
|
+
paddingBottom: bottom,
|
|
74
|
+
paddingLeft: left,
|
|
75
|
+
paddingRight: right
|
|
76
|
+
}), [bottom, left, right]);
|
|
77
|
+
const [baseRoute, ...sheetRoutes] = state.routes;
|
|
78
|
+
const baseDescriptor = baseRoute ? descriptors[baseRoute.key] : null;
|
|
79
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, baseDescriptor?.render(), sheetRoutes.map(route => {
|
|
131
80
|
const descriptor = descriptors[route.key];
|
|
132
81
|
if (!descriptor) return null;
|
|
133
82
|
const {
|
|
134
83
|
options,
|
|
135
|
-
navigation,
|
|
136
84
|
render
|
|
137
85
|
} = descriptor;
|
|
138
86
|
const {
|
|
139
|
-
index,
|
|
140
|
-
|
|
141
|
-
handleStyle,
|
|
87
|
+
index = 0,
|
|
88
|
+
style,
|
|
142
89
|
backgroundStyle,
|
|
143
90
|
handleIndicatorStyle,
|
|
144
|
-
|
|
145
|
-
...
|
|
91
|
+
handleStyle,
|
|
92
|
+
...props
|
|
146
93
|
} = options;
|
|
147
|
-
return /*#__PURE__*/React.createElement(
|
|
148
|
-
key: route.key
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
,
|
|
152
|
-
index: Math.min(route.snapToIndex ?? index ?? 0, !!snapPoints ? snapPoints.length - 1 : 0),
|
|
153
|
-
snapPoints: !snapPoints && !enableDynamicSizing ? DEFAULT_SNAP_POINTS : snapPoints,
|
|
154
|
-
onAnimate: (_, to) => {
|
|
155
|
-
// @ts-ignore TODO: Fix types
|
|
156
|
-
isFullScreen.value = ["%100", "100%"].includes(snapPoints?.[to]) ? 1 : 0;
|
|
157
|
-
},
|
|
158
|
-
animationConfigs: {
|
|
159
|
-
duration: 300,
|
|
160
|
-
easing: Easing.bezier(0.25, 0.1, 0.25, 1)
|
|
161
|
-
},
|
|
162
|
-
topInset: top + 18,
|
|
94
|
+
return /*#__PURE__*/React.createElement(BottomSheetScreen, _extends({
|
|
95
|
+
key: route.key,
|
|
96
|
+
id: route.key,
|
|
97
|
+
route: route,
|
|
98
|
+
index: index,
|
|
163
99
|
navigation: navigation,
|
|
164
|
-
|
|
100
|
+
style: [defaultStyle, style],
|
|
165
101
|
backgroundStyle: [themeBackgroundStyle, backgroundStyle],
|
|
166
102
|
handleIndicatorStyle: [themeHandleIndicatorStyle, handleIndicatorStyle],
|
|
167
103
|
handleStyle: [themeBackgroundStyle, {
|
|
168
|
-
borderRadius:
|
|
169
|
-
}, handleStyle]
|
|
170
|
-
|
|
171
|
-
|
|
104
|
+
borderRadius: 24
|
|
105
|
+
}, handleStyle],
|
|
106
|
+
onClose: data => {
|
|
107
|
+
navigation.dispatch({
|
|
108
|
+
...BottomSheetActions.remove(),
|
|
109
|
+
source: route.key
|
|
110
|
+
});
|
|
111
|
+
navigation.emit({
|
|
112
|
+
type: "sheetDismiss",
|
|
113
|
+
target: route.key,
|
|
114
|
+
data
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
onBeforeShow: data => {
|
|
118
|
+
navigation.emit({
|
|
119
|
+
type: "sheetPresent",
|
|
120
|
+
target: route.key,
|
|
121
|
+
data
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
onAnimate: (fromIndex, toIndex, fromPosition, toPosition) => {
|
|
125
|
+
navigation.emit({
|
|
126
|
+
type: "sheetOnAnimate",
|
|
127
|
+
target: route.key,
|
|
128
|
+
data: {
|
|
129
|
+
fromIndex,
|
|
130
|
+
toIndex,
|
|
131
|
+
fromPosition,
|
|
132
|
+
toPosition
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}, props), render());
|
|
137
|
+
}));
|
|
172
138
|
}
|
|
173
139
|
//# sourceMappingURL=view.js.map
|