@niibase/bottom-sheet-manager 1.3.0 → 1.4.1
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 +204 -193
- package/lib/commonjs/index.js +9 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/manager.js +56 -16
- package/lib/commonjs/manager.js.map +1 -1
- package/lib/commonjs/provider.js +41 -44
- package/lib/commonjs/provider.js.map +1 -1
- package/lib/commonjs/router/index.js +37 -7
- package/lib/commonjs/router/index.js.map +1 -1
- package/lib/commonjs/router/router.js.map +1 -1
- package/lib/commonjs/router/view.js +77 -220
- package/lib/commonjs/router/view.js.map +1 -1
- package/lib/commonjs/sheet.js +61 -85
- package/lib/commonjs/sheet.js.map +1 -1
- package/lib/module/index.js +2 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/manager.js +56 -16
- package/lib/module/manager.js.map +1 -1
- package/lib/module/provider.js +39 -42
- package/lib/module/provider.js.map +1 -1
- package/lib/module/router/index.js +39 -8
- package/lib/module/router/index.js.map +1 -1
- package/lib/module/router/router.js.map +1 -1
- package/lib/module/router/view.js +76 -220
- package/lib/module/router/view.js.map +1 -1
- package/lib/module/sheet.js +63 -87
- package/lib/module/sheet.js.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 +16 -0
- package/lib/typescript/manager.d.ts.map +1 -1
- package/lib/typescript/provider.d.ts +10 -23
- package/lib/typescript/provider.d.ts.map +1 -1
- package/lib/typescript/router/index.d.ts +21 -7
- package/lib/typescript/router/index.d.ts.map +1 -1
- package/lib/typescript/router/router.d.ts.map +1 -1
- package/lib/typescript/router/types.d.ts +75 -61
- 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 +32 -15
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +15 -15
- package/scripts/postinstall.mjs +36 -0
- package/src/index.ts +7 -7
- package/src/manager.ts +66 -22
- package/src/provider.tsx +72 -53
- package/src/router/index.tsx +46 -9
- package/src/router/router.ts +6 -2
- package/src/router/types.ts +109 -91
- package/src/router/view.tsx +86 -308
- package/src/sheet.tsx +111 -123
- package/src/types.ts +146 -133
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BottomSheetProps as RNBottomSheetProps } from "@gorhom/bottom-sheet";
|
|
2
2
|
import type { WithSpringConfig, WithTimingConfig } from "react-native-reanimated";
|
|
3
|
+
import { StatusBarStyle } from "react-native";
|
|
3
4
|
import React from "react";
|
|
4
5
|
export interface Sheets {
|
|
5
6
|
}
|
|
@@ -26,9 +27,30 @@ export interface SheetDefinition<Payload = never, ReturnValue = never> {
|
|
|
26
27
|
* - `replace`: Closes current sheet and opens new one. Previous sheet is
|
|
27
28
|
* removed from stack (not restored on close).
|
|
28
29
|
*
|
|
29
|
-
* - `push`:
|
|
30
|
+
* - `push`: Stacks new sheet on top. Previous sheet remains visible underneath.
|
|
30
31
|
*/
|
|
31
32
|
export type StackBehavior = "switch" | "replace" | "push";
|
|
33
|
+
export type SheetProviderProps = React.PropsWithChildren<{
|
|
34
|
+
context?: string;
|
|
35
|
+
/** @default default */
|
|
36
|
+
statusBar?: StatusBarStyle;
|
|
37
|
+
scaleConfig?: {
|
|
38
|
+
/** Scale factor when sheet is open (default: 0.92) */
|
|
39
|
+
scale?: number;
|
|
40
|
+
/** Vertical translation when sheet is open (default: 5) */
|
|
41
|
+
translateY?: number;
|
|
42
|
+
/** Border radius when sheet is open (default: 24) */
|
|
43
|
+
borderRadius?: number;
|
|
44
|
+
/** Animation config - timing or spring (default: timing with 300ms duration) */
|
|
45
|
+
animation?: {
|
|
46
|
+
type: "timing";
|
|
47
|
+
config?: WithTimingConfig;
|
|
48
|
+
} | {
|
|
49
|
+
type: "spring";
|
|
50
|
+
config?: WithSpringConfig;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
}>;
|
|
32
54
|
export interface BottomSheetInstance<Id extends SheetIds = SheetIds> {
|
|
33
55
|
/**
|
|
34
56
|
* Close the bottom sheet.
|
|
@@ -76,11 +98,11 @@ export interface BottomSheetInstance<Id extends SheetIds = SheetIds> {
|
|
|
76
98
|
*/
|
|
77
99
|
readonly snapToPosition: (position: string | number, animationConfigs?: AnimationConfigs) => void;
|
|
78
100
|
}
|
|
79
|
-
export type BottomSheetProps = Omit<RNBottomSheetProps, "children" | "onClose"> & {
|
|
101
|
+
export type BottomSheetProps<Id extends SheetIds = SheetIds> = Omit<RNBottomSheetProps, "children" | "onClose"> & {
|
|
80
102
|
/**
|
|
81
103
|
* ID of the `BottomSheet`.
|
|
82
104
|
*/
|
|
83
|
-
id?: SheetID<
|
|
105
|
+
id?: SheetID<Id>;
|
|
84
106
|
/**
|
|
85
107
|
* Content of the `BottomSheet`.
|
|
86
108
|
*/
|
|
@@ -91,23 +113,23 @@ export type BottomSheetProps = Omit<RNBottomSheetProps, "children" | "onClose">
|
|
|
91
113
|
*/
|
|
92
114
|
hardwareBackPressToClose?: boolean;
|
|
93
115
|
/**
|
|
94
|
-
* Callback when the sheet close
|
|
116
|
+
* Callback when the sheet closes. Return a value to override the close data
|
|
117
|
+
* forwarded to `SheetManager.show()` callers.
|
|
95
118
|
*
|
|
96
|
-
* @
|
|
97
|
-
* @returns The data returned by the sheet to be returned when closed.
|
|
119
|
+
* @returns Optionally return a new value to pass back to the caller.
|
|
98
120
|
*/
|
|
99
|
-
onClose?: (data?:
|
|
121
|
+
onClose?: (data?: SheetReturnValue<Id>) => SheetReturnValue<Id> | void;
|
|
100
122
|
/**
|
|
101
123
|
* Event called before sheets is visible.
|
|
102
124
|
* @param data Payload of the sheet if any.
|
|
103
125
|
* @type () => void;
|
|
104
126
|
*/
|
|
105
|
-
onBeforeShow?: (data?:
|
|
127
|
+
onBeforeShow?: (data?: SheetPayload<Id>) => void;
|
|
106
128
|
/**
|
|
107
129
|
* Can click through the sheet to the underlying view.
|
|
108
130
|
* @default false
|
|
109
131
|
*/
|
|
110
|
-
|
|
132
|
+
passThrough?: boolean;
|
|
111
133
|
/**
|
|
112
134
|
* Opacity of the sheet's overlay.
|
|
113
135
|
* @default 0.45
|
|
@@ -118,7 +140,7 @@ export type BottomSheetProps = Omit<RNBottomSheetProps, "children" | "onClose">
|
|
|
118
140
|
*
|
|
119
141
|
* - `switch`: (default) Dismisses the current sheet before showing the new one.
|
|
120
142
|
* - `replace`: Swaps the current sheet's content with smooth crossfade animation.
|
|
121
|
-
* - `push`:
|
|
143
|
+
* - `push`: Pushes new sheet on top, creating a navigable stack.
|
|
122
144
|
*
|
|
123
145
|
* @default "switch"
|
|
124
146
|
*/
|
|
@@ -130,11 +152,6 @@ export type BottomSheetProps = Omit<RNBottomSheetProps, "children" | "onClose">
|
|
|
130
152
|
* @default false
|
|
131
153
|
*/
|
|
132
154
|
iosModalSheetTypeOfAnimation?: boolean;
|
|
133
|
-
className?: string;
|
|
134
|
-
handleIndicatorClassName?: string;
|
|
135
|
-
backgroundClassName?: string;
|
|
136
|
-
containerClassName?: string;
|
|
137
|
-
handleClassName?: string;
|
|
138
155
|
};
|
|
139
156
|
export {};
|
|
140
157
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,MAAM;CAAG;AAC1B,MAAM,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;AACpC,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,QAAQ,IAAI,EAAE,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE9D,MAAM,MAAM,YAAY,CAAC,EAAE,SAAS,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;AACtE,MAAM,MAAM,gBAAgB,CAAC,EAAE,SAAS,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC;AAC9E,KAAK,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAE5D,MAAM,WAAW,UAAU,CAAC,EAAE,SAAS,QAAQ,GAAG,QAAQ;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@niibase/bottom-sheet-manager",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "A bottom sheet manager for react-native based on @gorhom/bottom-sheet",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
"build": "bob build && yarn copy-dts && yarn delete-dts.js",
|
|
15
15
|
"copy-dts": "copyfiles -u 1 \"src/**/*.d.ts\" lib/typescript",
|
|
16
16
|
"delete-dts.js": "find ./lib/commonjs -name '*.d.js*' -delete && find ./lib/module -name '*.d.js*' -delete",
|
|
17
|
-
"
|
|
17
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
18
|
+
"bootstrap": "yarn install && yarn example",
|
|
18
19
|
"example": "yarn --cwd example",
|
|
19
|
-
"
|
|
20
|
+
"patch": "patch-package"
|
|
20
21
|
},
|
|
21
22
|
"repository": {
|
|
22
23
|
"type": "git",
|
|
@@ -46,16 +47,17 @@
|
|
|
46
47
|
"files": [
|
|
47
48
|
"src",
|
|
48
49
|
"lib",
|
|
50
|
+
"scripts",
|
|
49
51
|
"LICENSE"
|
|
50
52
|
],
|
|
51
53
|
"peerDependencies": {
|
|
52
|
-
"@react-navigation/native": ">=
|
|
54
|
+
"@react-navigation/native": ">=7.1.8",
|
|
53
55
|
"@types/react": "*",
|
|
54
56
|
"@types/react-native": "*",
|
|
55
57
|
"react": "*",
|
|
56
58
|
"react-native": "*",
|
|
57
|
-
"react-native-gesture-handler": ">=2.
|
|
58
|
-
"react-native-reanimated": ">=3.16.0 || >=4.0.0
|
|
59
|
+
"react-native-gesture-handler": ">=2.28.0",
|
|
60
|
+
"react-native-reanimated": ">=3.16.0 || >=4.0.0",
|
|
59
61
|
"react-native-safe-area-context": "*"
|
|
60
62
|
},
|
|
61
63
|
"peerDependenciesMeta": {
|
|
@@ -67,27 +69,25 @@
|
|
|
67
69
|
}
|
|
68
70
|
},
|
|
69
71
|
"dependencies": {
|
|
70
|
-
"@gorhom/bottom-sheet": "^5.2.
|
|
72
|
+
"@gorhom/bottom-sheet": "^5.2.8",
|
|
71
73
|
"nanoid": "^5.1.6"
|
|
72
74
|
},
|
|
73
75
|
"devDependencies": {
|
|
74
|
-
"@
|
|
75
|
-
"@
|
|
76
|
-
"@ianvs/prettier-plugin-sort-imports": "file:patched/prettier-plugin-sort-imports",
|
|
77
|
-
"@react-navigation/native": "^7.1.9",
|
|
78
|
-
"@release-it/conventional-changelog": "^10.0.1",
|
|
76
|
+
"@ianvs/prettier-plugin-sort-imports": "4.7.0",
|
|
77
|
+
"@react-navigation/native": "^7.1.8",
|
|
79
78
|
"@types/react": "~18.3.12",
|
|
80
79
|
"@types/react-native": "~0.73.0",
|
|
81
80
|
"copyfiles": "^2.4.1",
|
|
82
81
|
"metro-react-native-babel-preset": "^0.77.0",
|
|
82
|
+
"patch-package": "^8.0.1",
|
|
83
83
|
"prettier": "3.6.2",
|
|
84
84
|
"react": "18.3.1",
|
|
85
85
|
"react-native": "0.76.0",
|
|
86
86
|
"react-native-builder-bob": "^0.23.2",
|
|
87
|
-
"react-native-gesture-handler": "~2.
|
|
87
|
+
"react-native-gesture-handler": "~2.28.0",
|
|
88
88
|
"react-native-reanimated": "~3.19.1",
|
|
89
89
|
"react-native-safe-area-context": "~5.6.0",
|
|
90
|
-
"
|
|
90
|
+
"react-native-screens": "~4.16.0",
|
|
91
91
|
"typescript": "^5.8.3"
|
|
92
92
|
},
|
|
93
93
|
"react-native-builder-bob": {
|
|
@@ -99,4 +99,4 @@
|
|
|
99
99
|
"typescript"
|
|
100
100
|
]
|
|
101
101
|
}
|
|
102
|
-
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
|
|
9
|
+
// Get the package root (one level up from scripts/)
|
|
10
|
+
const packageRoot = dirname(__dirname);
|
|
11
|
+
const maybeNodeModules = resolve(packageRoot, "../");
|
|
12
|
+
const isInNodeModules =
|
|
13
|
+
maybeNodeModules.endsWith("node_modules") ||
|
|
14
|
+
maybeNodeModules.endsWith("node_modules/@niibase");
|
|
15
|
+
|
|
16
|
+
if (isInNodeModules) {
|
|
17
|
+
// Fix keyboard not closing issue: https://github.com/gorhom/react-native-bottom-sheet/pull/2511
|
|
18
|
+
const gorhamBottomSheet = join(
|
|
19
|
+
maybeNodeModules,
|
|
20
|
+
"@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx",
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const content = readFileSync(gorhamBottomSheet, "utf-8");
|
|
25
|
+
const updated = content.replace(
|
|
26
|
+
/index\s*=\s*highestDetentPosition\s*\?\?\s*DEFAULT_KEYBOARD_INDEX\s*;/g,
|
|
27
|
+
"index = detents?.indexOf(highestDetentPosition ?? 0) ?? DEFAULT_KEYBOARD_INDEX;",
|
|
28
|
+
);
|
|
29
|
+
writeFileSync(gorhamBottomSheet, updated, "utf-8");
|
|
30
|
+
console.log("Applied patch for @gorhom/bottom-sheet");
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error("Error updating @gorhom/bottom-sheet:", error.message);
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
execSync("yarn run patch", { stdio: "inherit" });
|
|
36
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export { default as BottomSheet } from "./sheet";
|
|
2
|
-
export { SheetManager } from "./manager";
|
|
2
|
+
export { SheetManager, PrivateManager } from "./manager";
|
|
3
3
|
export * from "./router";
|
|
4
4
|
export * from "./types";
|
|
5
5
|
export {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
SheetProvider,
|
|
7
|
+
useSheetPayload,
|
|
8
|
+
useSheetRef,
|
|
9
|
+
useOnSheet,
|
|
10
|
+
useStackBehaviorContext as useSheetStackBehavior,
|
|
11
|
+
registerSheet,
|
|
12
12
|
} from "./provider";
|
package/src/manager.ts
CHANGED
|
@@ -25,16 +25,26 @@ export const PrivateManager = {
|
|
|
25
25
|
context(options?: { context?: string; id?: string }) {
|
|
26
26
|
if (!options) options = {};
|
|
27
27
|
if (!options?.context) {
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
// First try to find a context where this sheet is registered
|
|
29
|
+
if (options?.id) {
|
|
30
|
+
for (const context of providerRegistryStack.slice().reverse()) {
|
|
31
|
+
if (sheetsRegistry[context]?.[options.id]) {
|
|
32
|
+
options.context = context;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Fall back to the top-most auto-generated nested context
|
|
39
|
+
if (!options.context) {
|
|
40
|
+
for (const context of providerRegistryStack.slice().reverse()) {
|
|
41
|
+
if (
|
|
42
|
+
context.startsWith("$$-auto") &&
|
|
43
|
+
!context.includes(options?.id as string)
|
|
44
|
+
) {
|
|
45
|
+
options.context = context;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
38
48
|
}
|
|
39
49
|
}
|
|
40
50
|
}
|
|
@@ -130,6 +140,16 @@ export const PrivateManager = {
|
|
|
130
140
|
clearHistory: () => {
|
|
131
141
|
PrivateManager.history = [];
|
|
132
142
|
},
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Reset all internal state. Useful for testing or HMR.
|
|
146
|
+
*/
|
|
147
|
+
reset: () => {
|
|
148
|
+
ids.length = 0;
|
|
149
|
+
keys.length = 0;
|
|
150
|
+
for (const key in refs) delete refs[key];
|
|
151
|
+
PrivateManager.history = [];
|
|
152
|
+
},
|
|
133
153
|
};
|
|
134
154
|
|
|
135
155
|
class _SheetManager {
|
|
@@ -185,18 +205,21 @@ class _SheetManager {
|
|
|
185
205
|
|
|
186
206
|
const sub = eventManager.subscribe(`onclose_${id}`, handler);
|
|
187
207
|
|
|
188
|
-
// Handle existing sheets based on stack behavior
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
currentStack.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
208
|
+
// Handle existing sheets based on stack behavior.
|
|
209
|
+
// For "push" we do NOT hide existing sheets — they stay underneath.
|
|
210
|
+
if (behavior !== "push") {
|
|
211
|
+
const currentStack = PrivateManager.stack();
|
|
212
|
+
if (currentStack.length > 0) {
|
|
213
|
+
currentStack.forEach(({ id: sheetId, context }) => {
|
|
214
|
+
eventManager.publish(
|
|
215
|
+
`hide_${sheetId}`,
|
|
216
|
+
undefined,
|
|
217
|
+
context,
|
|
218
|
+
true,
|
|
219
|
+
behavior,
|
|
220
|
+
);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
200
223
|
}
|
|
201
224
|
|
|
202
225
|
// Check if the sheet is registered with any `SheetProviders`.
|
|
@@ -306,6 +329,7 @@ class _SheetManager {
|
|
|
306
329
|
/**
|
|
307
330
|
* Push a new sheet on top of the current one, creating a stack.
|
|
308
331
|
* This is a convenience method for show() with stackBehavior: 'push'.
|
|
332
|
+
*
|
|
309
333
|
*/
|
|
310
334
|
async push<SheetId extends keyof Sheets>(
|
|
311
335
|
id: SheetId | (string & {}),
|
|
@@ -329,6 +353,19 @@ class _SheetManager {
|
|
|
329
353
|
}
|
|
330
354
|
}
|
|
331
355
|
|
|
356
|
+
/**
|
|
357
|
+
* Get the internal ref of a sheet instance.
|
|
358
|
+
*
|
|
359
|
+
* @param id Id of the sheet
|
|
360
|
+
* @param context Optional context of the SheetProvider
|
|
361
|
+
*/
|
|
362
|
+
get<SheetId extends keyof Sheets>(
|
|
363
|
+
id: SheetId | (string & {}),
|
|
364
|
+
context?: string,
|
|
365
|
+
): BottomSheetInstance<SheetId> | undefined {
|
|
366
|
+
return PrivateManager.get(id, context)?.current ?? undefined;
|
|
367
|
+
}
|
|
368
|
+
|
|
332
369
|
/**
|
|
333
370
|
* Check if a specific sheet is currently visible.
|
|
334
371
|
*/
|
|
@@ -338,6 +375,13 @@ class _SheetManager {
|
|
|
338
375
|
): boolean {
|
|
339
376
|
return PrivateManager.isSheetVisible(id, context);
|
|
340
377
|
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Reset all internal state. Useful for testing environments.
|
|
381
|
+
*/
|
|
382
|
+
reset(): void {
|
|
383
|
+
PrivateManager.reset();
|
|
384
|
+
}
|
|
341
385
|
}
|
|
342
386
|
|
|
343
387
|
/**
|
package/src/provider.tsx
CHANGED
|
@@ -7,13 +7,20 @@ import Animated, {
|
|
|
7
7
|
useAnimatedStyle,
|
|
8
8
|
useSharedValue,
|
|
9
9
|
withSpring,
|
|
10
|
+
withTiming,
|
|
10
11
|
} from "react-native-reanimated";
|
|
11
12
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
12
13
|
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
|
|
13
14
|
import { StatusBar } from "react-native";
|
|
14
15
|
import React from "react";
|
|
15
16
|
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
BottomSheetInstance,
|
|
19
|
+
SheetPayload,
|
|
20
|
+
SheetProviderProps,
|
|
21
|
+
Sheets,
|
|
22
|
+
StackBehavior,
|
|
23
|
+
} from "./types";
|
|
17
24
|
import { eventManager } from "./events";
|
|
18
25
|
|
|
19
26
|
export const providerRegistryStack: string[] = [];
|
|
@@ -45,47 +52,33 @@ export function registerSheet<SheetId extends keyof Sheets = never>(
|
|
|
45
52
|
? (sheetsRegistry[context] = {})
|
|
46
53
|
: sheetsRegistry[context];
|
|
47
54
|
registry[id as string] = Sheet;
|
|
48
|
-
eventManager.
|
|
55
|
+
eventManager.publishAsync(`${context}-on-register`);
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
/**
|
|
53
|
-
* Animation configuration for iOS modal sheet style animations.
|
|
54
|
-
* @deprecated Use duration prop directly instead
|
|
55
|
-
*/
|
|
56
|
-
export interface ModalSheetAnimationConfig {
|
|
57
|
-
/** Duration of the animation in milliseconds */
|
|
58
|
-
duration: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
59
|
/**
|
|
62
60
|
* The SheetProvider makes available the sheets in a given context. The default context is
|
|
63
61
|
* `global`. However if you want to render a Sheet within another sheet or if you want to render
|
|
64
62
|
* Sheets in a modal. You can use a separate Provider with a custom context value.
|
|
65
63
|
*
|
|
66
|
-
*
|
|
64
|
+
* > **Note:** Context names must be unique across all `SheetProvider` instances.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
67
|
* ```ts
|
|
68
68
|
* // Define your SheetProvider in the component/modal where
|
|
69
69
|
* // you want to show some Sheets.
|
|
70
70
|
* <SheetProvider context="local-context" />
|
|
71
71
|
*
|
|
72
|
-
* // Then register your sheet
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* registerSheet('local-sheet', LocalSheet,'local-context');
|
|
76
|
-
*
|
|
72
|
+
* // Then register your sheet at module level (outside JSX):
|
|
73
|
+
* registerSheet('local-sheet', LocalSheet, 'local-context');
|
|
77
74
|
* ```
|
|
78
75
|
*/
|
|
79
76
|
export function SheetProvider({
|
|
80
|
-
iosModalSheetTypeOfAnimation = false,
|
|
81
77
|
context = "global",
|
|
82
|
-
|
|
78
|
+
statusBar,
|
|
79
|
+
scaleConfig,
|
|
83
80
|
children,
|
|
84
|
-
}:
|
|
85
|
-
context?: string;
|
|
86
|
-
duration?: number;
|
|
87
|
-
iosModalSheetTypeOfAnimation?: boolean;
|
|
88
|
-
}>) {
|
|
81
|
+
}: SheetProviderProps) {
|
|
89
82
|
const { top } = useSafeAreaInsets();
|
|
90
83
|
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
|
91
84
|
const sheetIds = Object.keys(sheetsRegistry[context] || sheetsRegistry["global"] || {});
|
|
@@ -94,33 +87,58 @@ export function SheetProvider({
|
|
|
94
87
|
const isFullScreen = useSharedValue(-1);
|
|
95
88
|
const colorStyle = useAnimatedStyle(() => ({
|
|
96
89
|
flex: 1,
|
|
97
|
-
backgroundColor:
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
backgroundColor: interpolateColor(
|
|
91
|
+
isFullScreen.value,
|
|
92
|
+
[0, 1],
|
|
93
|
+
["transparent", "#000"],
|
|
100
94
|
),
|
|
101
95
|
}));
|
|
102
|
-
const animatedStyle = useAnimatedStyle(
|
|
103
|
-
|
|
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 {
|
|
104
117
|
flex: 1,
|
|
105
118
|
overflow: "hidden",
|
|
106
|
-
borderRadius:
|
|
119
|
+
borderRadius:
|
|
120
|
+
scaleConfig?.animation?.type === "spring"
|
|
121
|
+
? withSpring(radius, scaleConfig.animation.config)
|
|
122
|
+
: withTiming(radius, scaleConfig?.animation?.config ?? { duration: 200 }),
|
|
107
123
|
transform: [
|
|
108
124
|
{
|
|
109
|
-
scaleX:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
scaleX:
|
|
126
|
+
scaleConfig?.animation?.type === "spring"
|
|
127
|
+
? withSpring(scale, scaleConfig.animation.config)
|
|
128
|
+
: withTiming(scale, scaleConfig?.animation?.config ?? { duration: 200 }),
|
|
113
129
|
},
|
|
114
130
|
{
|
|
115
|
-
translateY:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
131
|
+
translateY:
|
|
132
|
+
scaleConfig?.animation?.type === "spring"
|
|
133
|
+
? withSpring(translateY, scaleConfig.animation.config)
|
|
134
|
+
: withTiming(
|
|
135
|
+
translateY,
|
|
136
|
+
scaleConfig?.animation?.config ?? { duration: 200 },
|
|
137
|
+
),
|
|
119
138
|
},
|
|
120
139
|
],
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
);
|
|
140
|
+
};
|
|
141
|
+
}, [top, scaleConfig]);
|
|
124
142
|
|
|
125
143
|
// Since background color is white, we need to set status bar to light
|
|
126
144
|
const setStatusBar = StatusBar.setBarStyle;
|
|
@@ -128,8 +146,11 @@ export function SheetProvider({
|
|
|
128
146
|
() => isFullScreen.value,
|
|
129
147
|
(currentValue) => {
|
|
130
148
|
"worklet";
|
|
131
|
-
if (currentValue
|
|
132
|
-
runOnJS(setStatusBar)(
|
|
149
|
+
if (currentValue >= 0) {
|
|
150
|
+
runOnJS(setStatusBar)(
|
|
151
|
+
currentValue >= 0.5 ? "light-content" : (statusBar ?? "default"),
|
|
152
|
+
true,
|
|
153
|
+
);
|
|
133
154
|
}
|
|
134
155
|
},
|
|
135
156
|
[],
|
|
@@ -147,9 +168,7 @@ export function SheetProvider({
|
|
|
147
168
|
}, [context, forceUpdate]);
|
|
148
169
|
|
|
149
170
|
return (
|
|
150
|
-
<
|
|
151
|
-
value={{ isFullScreen, iosModalSheetTypeOfAnimation, duration }}
|
|
152
|
-
>
|
|
171
|
+
<SheetSharedContext.Provider value={{ isFullScreen, topInset: top }}>
|
|
153
172
|
<Animated.View style={colorStyle}>
|
|
154
173
|
<Animated.View style={animatedStyle}>{children}</Animated.View>
|
|
155
174
|
</Animated.View>
|
|
@@ -158,19 +177,18 @@ export function SheetProvider({
|
|
|
158
177
|
<RenderSheet key={id} id={id} context={context} />
|
|
159
178
|
))}
|
|
160
179
|
</BottomSheetModalProvider>
|
|
161
|
-
</
|
|
180
|
+
</SheetSharedContext.Provider>
|
|
162
181
|
);
|
|
163
182
|
}
|
|
183
|
+
|
|
164
184
|
const ProviderContext = React.createContext("global");
|
|
165
185
|
const SheetIDContext = React.createContext<string | undefined>(undefined);
|
|
166
|
-
const
|
|
167
|
-
iosModalSheetTypeOfAnimation: boolean;
|
|
186
|
+
const SheetSharedContext = React.createContext<{
|
|
168
187
|
isFullScreen: SharedValue<number>;
|
|
169
|
-
|
|
188
|
+
topInset: number;
|
|
170
189
|
}>({
|
|
171
190
|
isFullScreen: { value: 0 } as SharedValue<number>,
|
|
172
|
-
|
|
173
|
-
duration: 300,
|
|
191
|
+
topInset: 0,
|
|
174
192
|
});
|
|
175
193
|
|
|
176
194
|
export const SheetRefContext = React.createContext<
|
|
@@ -203,13 +221,14 @@ export const useSheetIDContext = () => React.useContext(SheetIDContext);
|
|
|
203
221
|
/**
|
|
204
222
|
* Get the current sheet animation context.
|
|
205
223
|
*/
|
|
206
|
-
export const
|
|
224
|
+
export const useSheetSharedContext = () => React.useContext(SheetSharedContext);
|
|
207
225
|
/**
|
|
208
226
|
* Get stack behavior context for the current sheet.
|
|
209
227
|
*/
|
|
210
228
|
export const useStackBehaviorContext = () => React.useContext(StackBehaviorContext);
|
|
211
229
|
/**
|
|
212
230
|
* Get the current Sheet's internal ref.
|
|
231
|
+
* Note: `current` may be null before the sheet is fully mounted.
|
|
213
232
|
*/
|
|
214
233
|
export const useSheetRef = <
|
|
215
234
|
SheetId extends keyof Sheets = never,
|