@niibase/bottom-sheet-manager 1.4.4 → 1.4.6
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 +230 -14
- package/lib/commonjs/index.js +10 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/router/view.js +2 -2
- package/lib/commonjs/router/view.js.map +1 -1
- package/lib/commonjs/{sheet.js → sheets/gorhom.js} +29 -74
- package/lib/commonjs/sheets/gorhom.js.map +1 -0
- package/lib/commonjs/sheets/shared.js +69 -0
- package/lib/commonjs/sheets/shared.js.map +1 -0
- package/lib/commonjs/sheets/truesheet.js +237 -0
- package/lib/commonjs/sheets/truesheet.js.map +1 -0
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/router/view.js +1 -1
- package/lib/module/router/view.js.map +1 -1
- package/lib/module/{sheet.js → sheets/gorhom.js} +29 -74
- package/lib/module/sheets/gorhom.js.map +1 -0
- package/lib/module/sheets/shared.js +60 -0
- package/lib/module/sheets/shared.js.map +1 -0
- package/lib/module/sheets/truesheet.js +230 -0
- package/lib/module/sheets/truesheet.js.map +1 -0
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/{sheet.d.ts → sheets/gorhom.d.ts} +2 -2
- package/lib/typescript/sheets/gorhom.d.ts.map +1 -0
- package/lib/typescript/sheets/shared.d.ts +15 -0
- package/lib/typescript/sheets/shared.d.ts.map +1 -0
- package/lib/typescript/sheets/truesheet.d.ts +23 -0
- package/lib/typescript/sheets/truesheet.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +5 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +13 -6
- package/src/index.ts +2 -1
- package/src/router/view.tsx +1 -1
- package/src/{sheet.tsx → sheets/gorhom.tsx} +31 -111
- package/src/sheets/shared.ts +108 -0
- package/src/sheets/truesheet.tsx +363 -0
- package/src/types.ts +6 -0
- package/lib/commonjs/sheet.js.map +0 -1
- package/lib/module/sheet.js.map +0 -1
- package/lib/typescript/sheet.d.ts.map +0 -1
|
@@ -11,6 +11,7 @@ import RNBottomSheet, {
|
|
|
11
11
|
BottomSheetView,
|
|
12
12
|
BottomSheetVirtualizedList,
|
|
13
13
|
} from "@gorhom/bottom-sheet";
|
|
14
|
+
import React from "react";
|
|
14
15
|
import {
|
|
15
16
|
BackHandler,
|
|
16
17
|
Platform,
|
|
@@ -19,23 +20,25 @@ import {
|
|
|
19
20
|
type NativeEventSubscription,
|
|
20
21
|
} from "react-native";
|
|
21
22
|
import {
|
|
23
|
+
Easing,
|
|
22
24
|
interpolate,
|
|
23
25
|
useAnimatedReaction,
|
|
24
26
|
useSharedValue,
|
|
27
|
+
type WithSpringConfig,
|
|
28
|
+
type WithTimingConfig,
|
|
25
29
|
} from "react-native-reanimated";
|
|
26
30
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
27
|
-
import React from "react";
|
|
28
31
|
|
|
32
|
+
import { PrivateManager } from "../manager";
|
|
29
33
|
import {
|
|
30
34
|
useProviderContext,
|
|
31
35
|
useSheetIDContext,
|
|
32
36
|
useSheetRef,
|
|
33
37
|
useSheetSharedContext,
|
|
34
38
|
useStackBehaviorContext,
|
|
35
|
-
} from "
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import { eventManager } from "./events";
|
|
39
|
+
} from "../provider";
|
|
40
|
+
import { useSheetManager, useTeardownSheet } from "./shared";
|
|
41
|
+
import { BottomSheetInstance, BottomSheetProps, SheetIds, StackBehavior } from "../types";
|
|
39
42
|
|
|
40
43
|
interface BottomSheetFC
|
|
41
44
|
extends React.MemoExoticComponent<React.ForwardRefExoticComponent<BottomSheetProps>> {
|
|
@@ -59,50 +62,9 @@ interface BottomSheetFC
|
|
|
59
62
|
const FULL_SCREEN_POINTS: (string | number)[] =
|
|
60
63
|
Platform.OS === "ios" ? ["%90", "90%"] : ["%93", "93%"];
|
|
61
64
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
onBeforeShow,
|
|
66
|
-
onContextUpdate,
|
|
67
|
-
}: {
|
|
68
|
-
id?: string;
|
|
69
|
-
onHide: (data?: unknown, dismiss?: boolean, behavior?: StackBehavior) => void;
|
|
70
|
-
onBeforeShow?: (data?: unknown, behavior?: StackBehavior) => void;
|
|
71
|
-
onContextUpdate: () => void;
|
|
72
|
-
}) => {
|
|
73
|
-
const currentContext = useProviderContext();
|
|
74
|
-
const hasShownRef = React.useRef(false);
|
|
75
|
-
|
|
76
|
-
React.useEffect(() => {
|
|
77
|
-
if (!id) return undefined;
|
|
78
|
-
|
|
79
|
-
const subscriptions = [
|
|
80
|
-
eventManager.subscribe(
|
|
81
|
-
`show_${id}`,
|
|
82
|
-
(data: unknown, context?: string, behavior?: StackBehavior) => {
|
|
83
|
-
if (currentContext !== context) return;
|
|
84
|
-
if (!hasShownRef.current) {
|
|
85
|
-
hasShownRef.current = true;
|
|
86
|
-
onContextUpdate?.();
|
|
87
|
-
onBeforeShow?.(data, behavior);
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
),
|
|
91
|
-
eventManager.subscribe(
|
|
92
|
-
`hide_${id}`,
|
|
93
|
-
(data: unknown, context: string, dismiss?: boolean, behavior?: StackBehavior) => {
|
|
94
|
-
if (currentContext !== context) return;
|
|
95
|
-
hasShownRef.current = false;
|
|
96
|
-
onHide?.(data, dismiss, behavior);
|
|
97
|
-
},
|
|
98
|
-
),
|
|
99
|
-
];
|
|
100
|
-
|
|
101
|
-
return () => {
|
|
102
|
-
hasShownRef.current = false;
|
|
103
|
-
subscriptions.forEach((s) => s?.unsubscribe?.());
|
|
104
|
-
};
|
|
105
|
-
}, [id, onHide, onBeforeShow, onContextUpdate, currentContext]);
|
|
65
|
+
const DEFAULT_SHEET_CLOSE_ANIMATION: WithTimingConfig = {
|
|
66
|
+
duration: 300,
|
|
67
|
+
easing: Easing.out(Easing.cubic),
|
|
106
68
|
};
|
|
107
69
|
|
|
108
70
|
const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetProps>(
|
|
@@ -121,6 +83,7 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
121
83
|
style,
|
|
122
84
|
passThrough,
|
|
123
85
|
opacity,
|
|
86
|
+
closeAnimationConfigs,
|
|
124
87
|
...props
|
|
125
88
|
},
|
|
126
89
|
ref,
|
|
@@ -135,11 +98,12 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
135
98
|
React.useState<StackBehavior>(stackBehavior);
|
|
136
99
|
const isPushed = currentStackBehavior === "push";
|
|
137
100
|
|
|
138
|
-
const { bottom
|
|
101
|
+
const { bottom } = useSafeAreaInsets();
|
|
102
|
+
const defaultStyle = React.useMemo(() => ({ paddingBottom: bottom }), [bottom]);
|
|
139
103
|
|
|
140
|
-
const
|
|
141
|
-
() =>
|
|
142
|
-
[
|
|
104
|
+
const effectiveCloseAnimation = React.useMemo(
|
|
105
|
+
() => closeAnimationConfigs ?? DEFAULT_SHEET_CLOSE_ANIMATION,
|
|
106
|
+
[closeAnimationConfigs],
|
|
143
107
|
);
|
|
144
108
|
|
|
145
109
|
const { fullScreenValues } = useSheetSharedContext();
|
|
@@ -170,6 +134,7 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
170
134
|
const teardownDataRef = React.useRef<{ dismiss?: boolean; behavior?: StackBehavior }>(
|
|
171
135
|
{},
|
|
172
136
|
);
|
|
137
|
+
const isClosingRef = React.useRef(false);
|
|
173
138
|
|
|
174
139
|
const id = useSheetIDContext();
|
|
175
140
|
const sheetId = props.id || id;
|
|
@@ -225,7 +190,7 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
225
190
|
);
|
|
226
191
|
const current = { ...fullScreenValues.value };
|
|
227
192
|
current[sheetId] = val;
|
|
228
|
-
fullScreenValues.
|
|
193
|
+
fullScreenValues.set(current);
|
|
229
194
|
}
|
|
230
195
|
},
|
|
231
196
|
[iosModalSheetTypeOfAnimation, sheetId],
|
|
@@ -236,58 +201,12 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
236
201
|
if (iosModalSheetTypeOfAnimation && sheetId) {
|
|
237
202
|
const current = { ...fullScreenValues.value };
|
|
238
203
|
delete current[sheetId];
|
|
239
|
-
fullScreenValues.
|
|
204
|
+
fullScreenValues.set(current);
|
|
240
205
|
}
|
|
241
206
|
};
|
|
242
207
|
}, [iosModalSheetTypeOfAnimation, sheetId, fullScreenValues]);
|
|
243
208
|
|
|
244
|
-
const teardownSheet =
|
|
245
|
-
(value: unknown, dismiss: boolean | undefined, behavior: StackBehavior) => {
|
|
246
|
-
if (!sheetId) return;
|
|
247
|
-
|
|
248
|
-
const hasHistory = PrivateManager.history.length > 0;
|
|
249
|
-
const shouldRestorePrevious = behavior !== "replace";
|
|
250
|
-
|
|
251
|
-
eventManager.publish(
|
|
252
|
-
`onclose_${sheetId}`,
|
|
253
|
-
value,
|
|
254
|
-
currentCtx,
|
|
255
|
-
hasHistory || !!dismiss,
|
|
256
|
-
behavior,
|
|
257
|
-
);
|
|
258
|
-
|
|
259
|
-
if (shouldRestorePrevious) {
|
|
260
|
-
if (dismiss) {
|
|
261
|
-
// it will surface naturally when the push sheet is closed.
|
|
262
|
-
if (behavior !== "push") {
|
|
263
|
-
PrivateManager.history.push({
|
|
264
|
-
id: sheetId,
|
|
265
|
-
context: currentCtx,
|
|
266
|
-
behavior: behavior,
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
} else if (hasHistory) {
|
|
270
|
-
const otherSheetsStillOpen = PrivateManager.stack().some(
|
|
271
|
-
(s) => !(s.id === sheetId && s.context === currentCtx),
|
|
272
|
-
);
|
|
273
|
-
if (!otherSheetsStillOpen) {
|
|
274
|
-
const prev = PrivateManager.history.pop()!;
|
|
275
|
-
eventManager.publish(
|
|
276
|
-
`show_wrap_${prev.id}`,
|
|
277
|
-
undefined,
|
|
278
|
-
prev.context,
|
|
279
|
-
true,
|
|
280
|
-
prev.behavior,
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
PrivateManager.remove(sheetId, currentCtx);
|
|
287
|
-
},
|
|
288
|
-
[sheetId, currentCtx],
|
|
289
|
-
);
|
|
290
|
-
|
|
209
|
+
const teardownSheet = useTeardownSheet({ sheetId, currentCtx });
|
|
291
210
|
const hideSheet = React.useCallback(
|
|
292
211
|
(
|
|
293
212
|
data?: unknown,
|
|
@@ -314,9 +233,11 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
314
233
|
const shouldClose = activeBehavior !== "replace" || !dismiss;
|
|
315
234
|
|
|
316
235
|
if (fromManager && shouldClose) {
|
|
236
|
+
if (isClosingRef.current) return;
|
|
237
|
+
isClosingRef.current = true;
|
|
317
238
|
valueRef.current = value;
|
|
318
239
|
teardownDataRef.current = { dismiss, behavior: activeBehavior };
|
|
319
|
-
bottomSheetRef.current?.close();
|
|
240
|
+
bottomSheetRef.current?.close(effectiveCloseAnimation);
|
|
320
241
|
return;
|
|
321
242
|
}
|
|
322
243
|
|
|
@@ -330,15 +251,11 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
330
251
|
const closeValue = onClose?.(value as never);
|
|
331
252
|
if (closeValue !== undefined) value = closeValue;
|
|
332
253
|
|
|
333
|
-
if (shouldClose) {
|
|
334
|
-
bottomSheetRef.current?.close();
|
|
335
|
-
}
|
|
336
|
-
|
|
337
254
|
teardownSheet(value, finalDismiss, finalBehavior);
|
|
338
|
-
|
|
255
|
+
isClosingRef.current = false;
|
|
339
256
|
if (fromManager) valueRef.current = data;
|
|
340
257
|
},
|
|
341
|
-
[currentStackBehavior, onClose, teardownSheet],
|
|
258
|
+
[currentStackBehavior, effectiveCloseAnimation, onClose, teardownSheet],
|
|
342
259
|
);
|
|
343
260
|
|
|
344
261
|
React.useEffect(() => {
|
|
@@ -349,7 +266,10 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
349
266
|
(): BottomSheetInstance => ({
|
|
350
267
|
close(options = {}): void {
|
|
351
268
|
valueRef.current = (options as Record<string, unknown>).value;
|
|
352
|
-
|
|
269
|
+
const opts = options as {
|
|
270
|
+
animationConfigs?: WithSpringConfig | WithTimingConfig;
|
|
271
|
+
};
|
|
272
|
+
bottomSheetRef.current?.close(opts.animationConfigs ?? effectiveCloseAnimation);
|
|
353
273
|
},
|
|
354
274
|
expand(animationConfigs): void {
|
|
355
275
|
bottomSheetRef.current?.expand(animationConfigs);
|
|
@@ -364,7 +284,7 @@ const BottomSheetComponent = React.forwardRef<BottomSheetInstance, BottomSheetPr
|
|
|
364
284
|
bottomSheetRef.current?.snapToPosition(position, animationConfigs);
|
|
365
285
|
},
|
|
366
286
|
}),
|
|
367
|
-
[],
|
|
287
|
+
[effectiveCloseAnimation],
|
|
368
288
|
);
|
|
369
289
|
|
|
370
290
|
React.useEffect(() => {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { eventManager } from "../events";
|
|
4
|
+
import { PrivateManager } from "../manager";
|
|
5
|
+
import { useProviderContext } from "../provider";
|
|
6
|
+
import { StackBehavior } from "../types";
|
|
7
|
+
|
|
8
|
+
type OnHide = (data?: unknown, dismiss?: boolean, behavior?: StackBehavior) => void;
|
|
9
|
+
type OnBeforeShow = (data?: unknown, behavior?: StackBehavior) => void;
|
|
10
|
+
|
|
11
|
+
export const useSheetManager = ({
|
|
12
|
+
id,
|
|
13
|
+
onHide,
|
|
14
|
+
onBeforeShow,
|
|
15
|
+
onContextUpdate,
|
|
16
|
+
}: {
|
|
17
|
+
id?: string;
|
|
18
|
+
onHide: OnHide;
|
|
19
|
+
onBeforeShow?: OnBeforeShow;
|
|
20
|
+
onContextUpdate: () => void;
|
|
21
|
+
}) => {
|
|
22
|
+
const currentContext = useProviderContext();
|
|
23
|
+
const hasShownRef = React.useRef(false);
|
|
24
|
+
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
if (!id) return undefined;
|
|
27
|
+
|
|
28
|
+
const subscriptions = [
|
|
29
|
+
eventManager.subscribe(
|
|
30
|
+
`show_${id}`,
|
|
31
|
+
(data: unknown, context?: string, behavior?: StackBehavior) => {
|
|
32
|
+
if (currentContext !== context) return;
|
|
33
|
+
if (!hasShownRef.current) {
|
|
34
|
+
hasShownRef.current = true;
|
|
35
|
+
onContextUpdate?.();
|
|
36
|
+
onBeforeShow?.(data, behavior);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
),
|
|
40
|
+
eventManager.subscribe(
|
|
41
|
+
`hide_${id}`,
|
|
42
|
+
(data: unknown, context: string, dismiss?: boolean, behavior?: StackBehavior) => {
|
|
43
|
+
if (currentContext !== context) return;
|
|
44
|
+
hasShownRef.current = false;
|
|
45
|
+
onHide?.(data, dismiss, behavior);
|
|
46
|
+
},
|
|
47
|
+
),
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
return () => {
|
|
51
|
+
hasShownRef.current = false;
|
|
52
|
+
subscriptions.forEach((s) => s?.unsubscribe?.());
|
|
53
|
+
};
|
|
54
|
+
}, [id, onHide, onBeforeShow, onContextUpdate, currentContext]);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const useTeardownSheet = ({
|
|
58
|
+
sheetId,
|
|
59
|
+
currentCtx,
|
|
60
|
+
}: {
|
|
61
|
+
sheetId?: string;
|
|
62
|
+
currentCtx: string;
|
|
63
|
+
}) =>
|
|
64
|
+
React.useCallback(
|
|
65
|
+
(value: unknown, dismiss: boolean | undefined, behavior: StackBehavior) => {
|
|
66
|
+
if (!sheetId) return;
|
|
67
|
+
|
|
68
|
+
const hasHistory = PrivateManager.history.length > 0;
|
|
69
|
+
const shouldRestorePrevious = behavior !== "replace";
|
|
70
|
+
|
|
71
|
+
eventManager.publish(
|
|
72
|
+
`onclose_${sheetId}`,
|
|
73
|
+
value,
|
|
74
|
+
currentCtx,
|
|
75
|
+
hasHistory || !!dismiss,
|
|
76
|
+
behavior,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (shouldRestorePrevious) {
|
|
80
|
+
if (dismiss) {
|
|
81
|
+
if (behavior !== "push") {
|
|
82
|
+
PrivateManager.history.push({
|
|
83
|
+
id: sheetId,
|
|
84
|
+
context: currentCtx,
|
|
85
|
+
behavior,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
} else if (hasHistory) {
|
|
89
|
+
const otherSheetsStillOpen = PrivateManager.stack().some(
|
|
90
|
+
(s) => !(s.id === sheetId && s.context === currentCtx),
|
|
91
|
+
);
|
|
92
|
+
if (!otherSheetsStillOpen) {
|
|
93
|
+
const prev = PrivateManager.history.pop()!;
|
|
94
|
+
eventManager.publish(
|
|
95
|
+
`show_wrap_${prev.id}`,
|
|
96
|
+
undefined,
|
|
97
|
+
prev.context,
|
|
98
|
+
true,
|
|
99
|
+
prev.behavior,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
PrivateManager.remove(sheetId, currentCtx);
|
|
106
|
+
},
|
|
107
|
+
[sheetId, currentCtx],
|
|
108
|
+
);
|