@lodev09/react-native-true-sheet 3.8.0-beta.1 → 3.8.0-beta.3
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/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +22 -2
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +29 -31
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +10 -9
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +6 -12
- package/ios/TrueSheetContainerView.mm +7 -0
- package/ios/TrueSheetContentView.mm +7 -1
- package/ios/TrueSheetModule.mm +33 -9
- package/ios/TrueSheetView.h +3 -1
- package/ios/TrueSheetView.mm +47 -40
- package/ios/TrueSheetViewController.h +1 -0
- package/ios/TrueSheetViewController.mm +4 -8
- package/ios/core/RNScreensEventObserver.mm +23 -15
- package/lib/module/TrueSheet.js +45 -26
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +26 -40
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetProvider.js +1 -0
- package/lib/module/TrueSheetProvider.js.map +1 -1
- package/lib/module/TrueSheetProvider.web.js +7 -32
- package/lib/module/TrueSheetProvider.web.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +3 -0
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/reanimated.js +2 -0
- package/lib/module/mocks/reanimated.js.map +1 -1
- package/lib/module/navigation/TrueSheetRouter.js +42 -8
- package/lib/module/navigation/TrueSheetRouter.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +8 -17
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/reanimated/ReanimatedTrueSheet.web.js +2 -2
- package/lib/module/reanimated/ReanimatedTrueSheet.web.js.map +1 -1
- package/lib/module/specs/NativeTrueSheetModule.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +29 -2
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +0 -48
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts +4 -2
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetProvider.d.ts +3 -2
- package/lib/typescript/src/TrueSheetProvider.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts +6 -14
- package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +6 -3
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/reanimated.d.ts +4 -2
- package/lib/typescript/src/mocks/reanimated.d.ts.map +1 -1
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts +4 -3
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts +9 -1
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/TrueSheet.tsx +45 -35
- package/src/TrueSheet.types.ts +0 -50
- package/src/TrueSheet.web.tsx +32 -50
- package/src/TrueSheetProvider.tsx +7 -2
- package/src/TrueSheetProvider.web.tsx +19 -38
- package/src/index.ts +1 -1
- package/src/mocks/index.ts +7 -6
- package/src/mocks/reanimated.ts +4 -5
- package/src/navigation/TrueSheetRouter.ts +51 -16
- package/src/navigation/screen/useSheetScreenState.ts +5 -11
- package/src/reanimated/ReanimatedTrueSheet.web.tsx +28 -30
- package/src/specs/NativeTrueSheetModule.ts +10 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { TrueSheet } from '../TrueSheet';
|
|
2
|
+
import type { TrueSheetProps } from '../TrueSheet.types';
|
|
2
3
|
interface ReanimatedTrueSheetProps extends TrueSheetProps {
|
|
3
4
|
/**
|
|
4
5
|
* Callback for position changes.
|
|
@@ -18,7 +19,7 @@ interface ReanimatedTrueSheetProps extends TrueSheetProps {
|
|
|
18
19
|
* import { ReanimatedTrueSheet, ReanimatedTrueSheetProvider } from '@lodev09/react-native-true-sheet/reanimated'
|
|
19
20
|
*
|
|
20
21
|
* function MyScreen() {
|
|
21
|
-
* const sheetRef = useRef<
|
|
22
|
+
* const sheetRef = useRef<TrueSheet>(null)
|
|
22
23
|
*
|
|
23
24
|
* return (
|
|
24
25
|
* <ReanimatedTrueSheetProvider>
|
|
@@ -36,6 +37,6 @@ interface ReanimatedTrueSheetProps extends TrueSheetProps {
|
|
|
36
37
|
* }
|
|
37
38
|
* ```
|
|
38
39
|
*/
|
|
39
|
-
export declare const ReanimatedTrueSheet: import("react").ForwardRefExoticComponent<ReanimatedTrueSheetProps & import("react").RefAttributes<
|
|
40
|
+
export declare const ReanimatedTrueSheet: import("react").ForwardRefExoticComponent<ReanimatedTrueSheetProps & import("react").RefAttributes<TrueSheet>>;
|
|
40
41
|
export {};
|
|
41
42
|
//# sourceMappingURL=ReanimatedTrueSheet.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReanimatedTrueSheet.web.d.ts","sourceRoot":"","sources":["../../../../src/reanimated/ReanimatedTrueSheet.web.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReanimatedTrueSheet.web.d.ts","sourceRoot":"","sources":["../../../../src/reanimated/ReanimatedTrueSheet.web.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAG9E,UAAU,wBAAyB,SAAQ,cAAc;IACvD;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC,kBAAkB,CAAC,CAAC;CACvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,mBAAmB,gHA8B9B,CAAC"}
|
|
@@ -16,13 +16,21 @@ interface Spec extends TurboModule {
|
|
|
16
16
|
*/
|
|
17
17
|
presentByRef(viewTag: number, index: number, animated: boolean): Promise<void>;
|
|
18
18
|
/**
|
|
19
|
-
* Dismiss a sheet
|
|
19
|
+
* Dismiss a sheet and all sheets presented on top of it
|
|
20
20
|
* @param viewTag - Native view tag of the sheet component
|
|
21
21
|
* @param animated - Whether to animate the dismissal
|
|
22
22
|
* @returns Promise that resolves when sheet is fully dismissed
|
|
23
23
|
* @throws DISMISS_FAILED if dismissal fails
|
|
24
24
|
*/
|
|
25
25
|
dismissByRef(viewTag: number, animated: boolean): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Dismiss only the sheets presented on top of this sheet, keeping this sheet presented
|
|
28
|
+
* @param viewTag - Native view tag of the sheet component
|
|
29
|
+
* @param animated - Whether to animate the dismissal
|
|
30
|
+
* @returns Promise that resolves when all child sheets are fully dismissed
|
|
31
|
+
* @throws DISMISS_FAILED if dismissal fails
|
|
32
|
+
*/
|
|
33
|
+
dismissStackByRef(viewTag: number, animated: boolean): Promise<void>;
|
|
26
34
|
/**
|
|
27
35
|
* Resize a sheet to a different index by reference
|
|
28
36
|
* @param viewTag - Native view tag of the sheet component
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeTrueSheetModule.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeTrueSheetModule.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,UAAU,IAAK,SAAQ,WAAW;IAChC;;;;;;;OAOG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/E;;;;;;OAMG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;OAIG;IACH,UAAU,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;;AAED,wBAAgE"}
|
|
1
|
+
{"version":3,"file":"NativeTrueSheetModule.d.ts","sourceRoot":"","sources":["../../../../src/specs/NativeTrueSheetModule.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,UAAU,IAAK,SAAQ,WAAW;IAChC;;;;;;;OAOG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/E;;;;;;OAMG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;;;;OAMG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;OAIG;IACH,UAAU,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;;AAED,wBAAgE"}
|
package/package.json
CHANGED
package/src/TrueSheet.tsx
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
|
|
11
11
|
import type {
|
|
12
12
|
TrueSheetProps,
|
|
13
|
-
TrueSheetRef,
|
|
14
13
|
DragBeginEvent,
|
|
15
14
|
DragChangeEvent,
|
|
16
15
|
DragEndEvent,
|
|
@@ -54,10 +53,7 @@ interface TrueSheetState {
|
|
|
54
53
|
shouldRenderNativeView: boolean;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
export class TrueSheet
|
|
58
|
-
extends PureComponent<TrueSheetProps, TrueSheetState>
|
|
59
|
-
implements TrueSheetRef
|
|
60
|
-
{
|
|
56
|
+
export class TrueSheet extends PureComponent<TrueSheetProps, TrueSheetState> {
|
|
61
57
|
displayName = 'TrueSheet';
|
|
62
58
|
|
|
63
59
|
private readonly nativeRef: RefObject<NativeRef | null>;
|
|
@@ -199,6 +195,22 @@ export class TrueSheet
|
|
|
199
195
|
return instance.dismiss(animated);
|
|
200
196
|
}
|
|
201
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Dismiss only the sheets presented on top of a sheet by given `name`
|
|
200
|
+
* @param name - Sheet name
|
|
201
|
+
* @param animated - Whether to animate the dismissal (default: true)
|
|
202
|
+
* @returns Promise that resolves when all child sheets are dismissed
|
|
203
|
+
* @throws Error if sheet not found
|
|
204
|
+
*/
|
|
205
|
+
public static async dismissStack(name: string, animated: boolean = true): Promise<void> {
|
|
206
|
+
const instance = TrueSheet.getInstance(name);
|
|
207
|
+
if (!instance) {
|
|
208
|
+
throw new Error(`Sheet with name "${name}" not found`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return instance.dismissStack(animated);
|
|
212
|
+
}
|
|
213
|
+
|
|
202
214
|
/**
|
|
203
215
|
* Resize the sheet by given `name` (Promise-based)
|
|
204
216
|
* @param name - Sheet name
|
|
@@ -309,6 +321,11 @@ export class TrueSheet
|
|
|
309
321
|
this.props.onBackPress?.(event);
|
|
310
322
|
}
|
|
311
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Present the sheet at a given detent index.
|
|
326
|
+
* @param index - The detent index to present at (default: 0)
|
|
327
|
+
* @param animated - Whether to animate the presentation (default: true)
|
|
328
|
+
*/
|
|
312
329
|
public async present(index: number = 0, animated: boolean = true): Promise<void> {
|
|
313
330
|
const detentsLength = Math.min(this.props.detents?.length ?? 2, 3); // Max 3 detents
|
|
314
331
|
if (index < 0 || index >= detentsLength) {
|
|
@@ -331,14 +348,31 @@ export class TrueSheet
|
|
|
331
348
|
this.isPresenting = false;
|
|
332
349
|
}
|
|
333
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Resize the sheet to a given detent index.
|
|
353
|
+
* @param index - The detent index to resize to
|
|
354
|
+
*/
|
|
334
355
|
public async resize(index: number): Promise<void> {
|
|
335
356
|
await TrueSheetModule?.resizeByRef(this.handle, index);
|
|
336
357
|
}
|
|
337
358
|
|
|
359
|
+
/**
|
|
360
|
+
* Dismiss this sheet and all sheets presented on top of it in a single animation.
|
|
361
|
+
* @param animated - Whether to animate the dismissal (default: true)
|
|
362
|
+
*/
|
|
338
363
|
public async dismiss(animated: boolean = true): Promise<void> {
|
|
339
364
|
return TrueSheetModule?.dismissByRef(this.handle, animated);
|
|
340
365
|
}
|
|
341
366
|
|
|
367
|
+
/**
|
|
368
|
+
* Dismiss only the sheets presented on top of this sheet, keeping this sheet presented.
|
|
369
|
+
* If no sheets are presented on top, this method does nothing.
|
|
370
|
+
* @param animated - Whether to animate the dismissal (default: true)
|
|
371
|
+
*/
|
|
372
|
+
public async dismissStack(animated: boolean = true): Promise<void> {
|
|
373
|
+
return TrueSheetModule?.dismissStackByRef(this.handle, animated);
|
|
374
|
+
}
|
|
375
|
+
|
|
342
376
|
componentDidMount(): void {
|
|
343
377
|
this.registerInstance();
|
|
344
378
|
}
|
|
@@ -400,23 +434,11 @@ export class TrueSheet
|
|
|
400
434
|
return Math.min(1, detent);
|
|
401
435
|
});
|
|
402
436
|
|
|
403
|
-
const containerStyle =
|
|
404
|
-
this.props.scrollable &&
|
|
405
|
-
Platform.select({
|
|
406
|
-
android: styles.scrollableAndroidContainer,
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
const contentStyle =
|
|
410
|
-
this.props.scrollable &&
|
|
411
|
-
Platform.select({
|
|
412
|
-
android: styles.scrollableAndroidContent,
|
|
413
|
-
});
|
|
414
|
-
|
|
415
437
|
return (
|
|
416
438
|
<TrueSheetViewNativeComponent
|
|
417
439
|
{...rest}
|
|
418
440
|
ref={this.nativeRef}
|
|
419
|
-
style={styles.sheetView}
|
|
441
|
+
style={[StyleSheet.absoluteFill, styles.sheetView]}
|
|
420
442
|
detents={resolvedDetents}
|
|
421
443
|
backgroundBlur={backgroundBlur}
|
|
422
444
|
blurOptions={blurOptions}
|
|
@@ -455,13 +477,15 @@ export class TrueSheet
|
|
|
455
477
|
onBackPress={this.onBackPress}
|
|
456
478
|
>
|
|
457
479
|
{this.state.shouldRenderNativeView && (
|
|
458
|
-
<TrueSheetContainerViewNativeComponent style={
|
|
480
|
+
<TrueSheetContainerViewNativeComponent style={scrollable && StyleSheet.absoluteFill}>
|
|
459
481
|
{header && (
|
|
460
482
|
<TrueSheetHeaderViewNativeComponent style={[styles.header, headerStyle]}>
|
|
461
483
|
{isValidElement(header) ? header : createElement(header)}
|
|
462
484
|
</TrueSheetHeaderViewNativeComponent>
|
|
463
485
|
)}
|
|
464
|
-
<TrueSheetContentViewNativeComponent
|
|
486
|
+
<TrueSheetContentViewNativeComponent
|
|
487
|
+
style={[style, scrollable && styles.scrollableContent]}
|
|
488
|
+
>
|
|
465
489
|
{children}
|
|
466
490
|
</TrueSheetContentViewNativeComponent>
|
|
467
491
|
{footer && (
|
|
@@ -480,22 +504,8 @@ const styles = StyleSheet.create({
|
|
|
480
504
|
sheetView: {
|
|
481
505
|
zIndex: -9999,
|
|
482
506
|
pointerEvents: 'box-none',
|
|
483
|
-
position: 'absolute',
|
|
484
|
-
top: 0,
|
|
485
|
-
left: 0,
|
|
486
|
-
right: 0,
|
|
487
|
-
|
|
488
|
-
// Android needs a fixed bottom to avoid jumping content
|
|
489
|
-
bottom: Platform.select({ android: 0 }),
|
|
490
|
-
},
|
|
491
|
-
scrollableAndroidContainer: {
|
|
492
|
-
position: 'absolute',
|
|
493
|
-
top: 0,
|
|
494
|
-
left: 0,
|
|
495
|
-
right: 0,
|
|
496
|
-
bottom: 0,
|
|
497
507
|
},
|
|
498
|
-
|
|
508
|
+
scrollableContent: {
|
|
499
509
|
flexGrow: 1,
|
|
500
510
|
flexBasis: 0,
|
|
501
511
|
},
|
package/src/TrueSheet.types.ts
CHANGED
|
@@ -46,56 +46,6 @@ export type WillFocusEvent = NativeSyntheticEvent<null>;
|
|
|
46
46
|
export type WillBlurEvent = NativeSyntheticEvent<null>;
|
|
47
47
|
export type BackPressEvent = NativeSyntheticEvent<null>;
|
|
48
48
|
|
|
49
|
-
/**
|
|
50
|
-
* Ref methods exposed by a TrueSheet instance.
|
|
51
|
-
*/
|
|
52
|
-
export interface TrueSheetRef {
|
|
53
|
-
/**
|
|
54
|
-
* Present the sheet at a given detent index.
|
|
55
|
-
* @param index - The detent index to present at (default: 0)
|
|
56
|
-
* @param animated - Whether to animate the presentation (default: true)
|
|
57
|
-
*/
|
|
58
|
-
present: (index?: number, animated?: boolean) => Promise<void>;
|
|
59
|
-
/**
|
|
60
|
-
* Dismiss the sheet. If other sheets are presented on top, dismisses them instead.
|
|
61
|
-
* @param animated - Whether to animate the dismissal (default: true)
|
|
62
|
-
*/
|
|
63
|
-
dismiss: (animated?: boolean) => Promise<void>;
|
|
64
|
-
/**
|
|
65
|
-
* Resize the sheet to a given detent index.
|
|
66
|
-
* @param index - The detent index to resize to
|
|
67
|
-
*/
|
|
68
|
-
resize: (index: number) => Promise<void>;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Methods for controlling TrueSheet instances by name.
|
|
73
|
-
* Returned by the `useTrueSheet` hook.
|
|
74
|
-
*/
|
|
75
|
-
export interface TrueSheetContextMethods {
|
|
76
|
-
/**
|
|
77
|
-
* Present a sheet by name.
|
|
78
|
-
* @param name - The name of the sheet to present
|
|
79
|
-
* @param index - The detent index to present at (default: 0)
|
|
80
|
-
*/
|
|
81
|
-
present: (name: string, index?: number) => Promise<void>;
|
|
82
|
-
/**
|
|
83
|
-
* Dismiss a sheet by name.
|
|
84
|
-
* @param name - The name of the sheet to dismiss
|
|
85
|
-
*/
|
|
86
|
-
dismiss: (name: string) => Promise<void>;
|
|
87
|
-
/**
|
|
88
|
-
* Resize a sheet by name.
|
|
89
|
-
* @param name - The name of the sheet to resize
|
|
90
|
-
* @param index - The detent index to resize to
|
|
91
|
-
*/
|
|
92
|
-
resize: (name: string, index: number) => Promise<void>;
|
|
93
|
-
/**
|
|
94
|
-
* Dismiss all presented sheets.
|
|
95
|
-
*/
|
|
96
|
-
dismissAll: () => Promise<void>;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
49
|
/**
|
|
100
50
|
* Options for customizing the grabber (drag handle) appearance.
|
|
101
51
|
*/
|
package/src/TrueSheet.web.tsx
CHANGED
|
@@ -27,16 +27,9 @@ import BottomSheet, {
|
|
|
27
27
|
} from '@gorhom/bottom-sheet';
|
|
28
28
|
import { useDerivedValue, useSharedValue } from 'react-native-reanimated';
|
|
29
29
|
|
|
30
|
-
import {
|
|
31
|
-
BottomSheetContext,
|
|
32
|
-
getPresent,
|
|
33
|
-
getDismiss,
|
|
34
|
-
getResize,
|
|
35
|
-
getDismissAll,
|
|
36
|
-
} from './TrueSheetProvider.web';
|
|
30
|
+
import { BottomSheetContext, type TrueSheetRefMethods } from './TrueSheetProvider.web';
|
|
37
31
|
import type {
|
|
38
32
|
TrueSheetProps,
|
|
39
|
-
TrueSheetRef,
|
|
40
33
|
DetentChangeEvent,
|
|
41
34
|
DidBlurEvent,
|
|
42
35
|
DidDismissEvent,
|
|
@@ -84,7 +77,7 @@ const renderSlot = (slot: TrueSheetProps['header'] | TrueSheetProps['footer']) =
|
|
|
84
77
|
return createElement(slot);
|
|
85
78
|
};
|
|
86
79
|
|
|
87
|
-
const TrueSheetComponent = forwardRef<
|
|
80
|
+
const TrueSheetComponent = forwardRef<TrueSheetRefMethods, TrueSheetProps>((props, ref) => {
|
|
88
81
|
const {
|
|
89
82
|
name,
|
|
90
83
|
detents = [0.5, 1],
|
|
@@ -362,19 +355,7 @@ const TrueSheetComponent = forwardRef<TrueSheetRef, TrueSheetProps>((props, ref)
|
|
|
362
355
|
// For scrollable, we render the child directly
|
|
363
356
|
const ContainerComponent = scrollable ? Fragment : BottomSheetView;
|
|
364
357
|
|
|
365
|
-
const
|
|
366
|
-
return new Promise<void>((resolve) => {
|
|
367
|
-
dismissResolver.current = resolve;
|
|
368
|
-
isDismissing.current = true;
|
|
369
|
-
if (isNonModal) {
|
|
370
|
-
bottomSheetRef.current?.close();
|
|
371
|
-
} else {
|
|
372
|
-
bottomSheetModalRef.current?.dismiss();
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
}, [isNonModal]);
|
|
376
|
-
|
|
377
|
-
const sheetMethodsRef = useRef<TrueSheetRef & { dismissDirect?: () => Promise<void> }>({
|
|
358
|
+
const sheetMethodsRef = useRef<TrueSheetRefMethods>({
|
|
378
359
|
present: (index = 0) => {
|
|
379
360
|
return new Promise<void>((resolve) => {
|
|
380
361
|
presentResolver.current = resolve;
|
|
@@ -390,20 +371,29 @@ const TrueSheetComponent = forwardRef<TrueSheetRef, TrueSheetProps>((props, ref)
|
|
|
390
371
|
},
|
|
391
372
|
dismiss: () => {
|
|
392
373
|
return new Promise<void>((resolve) => {
|
|
393
|
-
|
|
394
|
-
|
|
374
|
+
dismissResolver.current = resolve;
|
|
375
|
+
isDismissing.current = true;
|
|
376
|
+
if (isNonModal) {
|
|
377
|
+
bottomSheetRef.current?.close();
|
|
378
|
+
} else {
|
|
379
|
+
bottomSheetModalRef.current?.dismiss();
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
},
|
|
383
|
+
dismissStack: () => {
|
|
384
|
+
return new Promise<void>((resolve) => {
|
|
385
|
+
// Dismiss only sheets above, keeping this sheet presented
|
|
395
386
|
const sheetsAbove = bottomSheetContext?.getSheetsAbove(sheetName) ?? [];
|
|
396
387
|
const immediateChild = sheetsAbove[sheetsAbove.length - 1];
|
|
397
388
|
if (immediateChild) {
|
|
398
389
|
// Dismiss the immediate child - gorhom will dismiss all sheets above it
|
|
399
|
-
bottomSheetContext?.
|
|
390
|
+
bottomSheetContext?.dismiss(immediateChild).then(resolve);
|
|
400
391
|
return;
|
|
401
392
|
}
|
|
402
393
|
|
|
403
|
-
|
|
394
|
+
resolve();
|
|
404
395
|
});
|
|
405
396
|
},
|
|
406
|
-
dismissDirect: () => dismissInternal(),
|
|
407
397
|
resize: async (index: number) => {
|
|
408
398
|
if (isNonModal) {
|
|
409
399
|
bottomSheetRef.current?.snapToIndex(index);
|
|
@@ -494,45 +484,37 @@ const TrueSheetComponent = forwardRef<TrueSheetRef, TrueSheetProps>((props, ref)
|
|
|
494
484
|
);
|
|
495
485
|
});
|
|
496
486
|
|
|
487
|
+
const STATIC_METHOD_ERROR =
|
|
488
|
+
'Static methods are not supported on web. Use the useTrueSheet() hook instead.';
|
|
489
|
+
|
|
497
490
|
interface TrueSheetStatic {
|
|
498
491
|
present: (name: string, index?: number) => Promise<void>;
|
|
499
492
|
dismiss: (name: string) => Promise<void>;
|
|
493
|
+
dismissStack: (name: string) => Promise<void>;
|
|
500
494
|
resize: (name: string, index: number) => Promise<void>;
|
|
501
495
|
dismissAll: () => Promise<void>;
|
|
502
496
|
}
|
|
503
497
|
|
|
504
498
|
export const TrueSheet = TrueSheetComponent as typeof TrueSheetComponent & TrueSheetStatic;
|
|
505
499
|
|
|
506
|
-
TrueSheet.present = async (
|
|
507
|
-
|
|
508
|
-
if (!present) {
|
|
509
|
-
throw new Error('TrueSheet.present(): TrueSheetProvider is not mounted.');
|
|
510
|
-
}
|
|
511
|
-
return present(name, index);
|
|
500
|
+
TrueSheet.present = async () => {
|
|
501
|
+
throw new Error(STATIC_METHOD_ERROR);
|
|
512
502
|
};
|
|
513
503
|
|
|
514
|
-
TrueSheet.dismiss = async (
|
|
515
|
-
|
|
516
|
-
if (!dismiss) {
|
|
517
|
-
throw new Error('TrueSheet.dismiss(): TrueSheetProvider is not mounted.');
|
|
518
|
-
}
|
|
519
|
-
return dismiss(name);
|
|
504
|
+
TrueSheet.dismiss = async () => {
|
|
505
|
+
throw new Error(STATIC_METHOD_ERROR);
|
|
520
506
|
};
|
|
521
507
|
|
|
522
|
-
TrueSheet.
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
508
|
+
TrueSheet.dismissStack = async () => {
|
|
509
|
+
throw new Error(STATIC_METHOD_ERROR);
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
TrueSheet.resize = async () => {
|
|
513
|
+
throw new Error(STATIC_METHOD_ERROR);
|
|
528
514
|
};
|
|
529
515
|
|
|
530
516
|
TrueSheet.dismissAll = async () => {
|
|
531
|
-
|
|
532
|
-
if (!dismissAll) {
|
|
533
|
-
throw new Error('TrueSheet.dismissAll(): TrueSheetProvider is not mounted.');
|
|
534
|
-
}
|
|
535
|
-
return dismissAll();
|
|
517
|
+
throw new Error(STATIC_METHOD_ERROR);
|
|
536
518
|
};
|
|
537
519
|
|
|
538
520
|
const styles = StyleSheet.create({
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import { TrueSheet } from './TrueSheet';
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
export type TrueSheetStaticMethods = Pick<
|
|
6
|
+
typeof TrueSheet,
|
|
7
|
+
'present' | 'dismiss' | 'dismissStack' | 'resize' | 'dismissAll'
|
|
8
|
+
>;
|
|
5
9
|
|
|
6
10
|
export interface TrueSheetProviderProps {
|
|
7
11
|
children: ReactNode;
|
|
@@ -20,10 +24,11 @@ export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
|
20
24
|
* Hook to control TrueSheet instances by name.
|
|
21
25
|
* On native, this maps directly to TrueSheet static methods.
|
|
22
26
|
*/
|
|
23
|
-
export function useTrueSheet():
|
|
27
|
+
export function useTrueSheet(): TrueSheetStaticMethods {
|
|
24
28
|
return {
|
|
25
29
|
present: TrueSheet.present,
|
|
26
30
|
dismiss: TrueSheet.dismiss,
|
|
31
|
+
dismissStack: TrueSheet.dismissStack,
|
|
27
32
|
resize: TrueSheet.resize,
|
|
28
33
|
dismissAll: TrueSheet.dismissAll,
|
|
29
34
|
};
|
|
@@ -1,30 +1,24 @@
|
|
|
1
1
|
import { createContext, useContext, useRef, type ReactNode, type RefObject } from 'react';
|
|
2
2
|
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
|
|
3
|
-
import type { TrueSheetContextMethods, TrueSheetRef } from './TrueSheet.types';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import type { TrueSheetStaticMethods } from './TrueSheetProvider';
|
|
5
|
+
import type { TrueSheet } from './TrueSheet';
|
|
6
|
+
|
|
7
|
+
export type TrueSheetRefMethods = Pick<
|
|
8
|
+
TrueSheet,
|
|
9
|
+
'present' | 'dismiss' | 'resize' | 'dismissStack'
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
interface BottomSheetContextValue extends TrueSheetStaticMethods {
|
|
13
|
+
register: (name: string, methods: RefObject<TrueSheetRefMethods>) => void;
|
|
7
14
|
unregister: (name: string) => void;
|
|
8
15
|
pushToStack: (name: string) => void;
|
|
9
16
|
removeFromStack: (name: string) => void;
|
|
10
17
|
getSheetsAbove: (name: string) => string[];
|
|
11
|
-
dismissDirect: (name: string) => Promise<void>;
|
|
12
|
-
dismissAll: () => Promise<void>;
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
export const BottomSheetContext = createContext<BottomSheetContextValue | null>(null);
|
|
16
21
|
|
|
17
|
-
// Module-level references for static methods
|
|
18
|
-
let presentRef: ((name: string, index?: number) => Promise<void>) | null = null;
|
|
19
|
-
let dismissRef: ((name: string) => Promise<void>) | null = null;
|
|
20
|
-
let resizeRef: ((name: string, index: number) => Promise<void>) | null = null;
|
|
21
|
-
let dismissAllRef: (() => Promise<void>) | null = null;
|
|
22
|
-
|
|
23
|
-
export const getPresent = () => presentRef;
|
|
24
|
-
export const getDismiss = () => dismissRef;
|
|
25
|
-
export const getResize = () => resizeRef;
|
|
26
|
-
export const getDismissAll = () => dismissAllRef;
|
|
27
|
-
|
|
28
22
|
export interface TrueSheetProviderProps {
|
|
29
23
|
children: ReactNode;
|
|
30
24
|
}
|
|
@@ -34,10 +28,10 @@ export interface TrueSheetProviderProps {
|
|
|
34
28
|
* Required to wrap your app for sheet management via useTrueSheet hook.
|
|
35
29
|
*/
|
|
36
30
|
export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
37
|
-
const sheetsRef = useRef<Map<string, RefObject<
|
|
31
|
+
const sheetsRef = useRef<Map<string, RefObject<TrueSheetRefMethods>>>(new Map());
|
|
38
32
|
const presentedStackRef = useRef<string[]>([]);
|
|
39
33
|
|
|
40
|
-
const register = (name: string, methods: RefObject<
|
|
34
|
+
const register = (name: string, methods: RefObject<TrueSheetRefMethods>) => {
|
|
41
35
|
sheetsRef.current.set(name, methods);
|
|
42
36
|
};
|
|
43
37
|
|
|
@@ -88,17 +82,13 @@ export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
|
88
82
|
return sheet.current.dismiss();
|
|
89
83
|
};
|
|
90
84
|
|
|
91
|
-
|
|
92
|
-
* Dismisses a sheet directly without checking for sheets above.
|
|
93
|
-
* Used internally when batch-dismissing stacked sheets.
|
|
94
|
-
*/
|
|
95
|
-
const dismissDirect = async (name: string) => {
|
|
85
|
+
const dismissStack = async (name: string) => {
|
|
96
86
|
const sheet = sheetsRef.current.get(name);
|
|
97
87
|
if (!sheet?.current) {
|
|
98
88
|
console.warn(`TrueSheet: Could not find sheet with name "${name}"`);
|
|
99
89
|
return;
|
|
100
90
|
}
|
|
101
|
-
return
|
|
91
|
+
return sheet.current.dismissStack();
|
|
102
92
|
};
|
|
103
93
|
|
|
104
94
|
const resize = async (name: string, index: number) => {
|
|
@@ -113,15 +103,9 @@ export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
|
113
103
|
const dismissAll = async () => {
|
|
114
104
|
const rootSheet = presentedStackRef.current[0];
|
|
115
105
|
if (!rootSheet) return;
|
|
116
|
-
return
|
|
106
|
+
return dismiss(rootSheet);
|
|
117
107
|
};
|
|
118
108
|
|
|
119
|
-
// Set module-level refs for static access
|
|
120
|
-
presentRef = present;
|
|
121
|
-
dismissRef = dismiss;
|
|
122
|
-
resizeRef = resize;
|
|
123
|
-
dismissAllRef = dismissAll;
|
|
124
|
-
|
|
125
109
|
return (
|
|
126
110
|
<BottomSheetContext.Provider
|
|
127
111
|
value={{
|
|
@@ -130,11 +114,11 @@ export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
|
130
114
|
pushToStack,
|
|
131
115
|
removeFromStack,
|
|
132
116
|
getSheetsAbove,
|
|
133
|
-
dismissDirect,
|
|
134
|
-
dismissAll,
|
|
135
117
|
present,
|
|
136
118
|
dismiss,
|
|
119
|
+
dismissStack,
|
|
137
120
|
resize,
|
|
121
|
+
dismissAll,
|
|
138
122
|
}}
|
|
139
123
|
>
|
|
140
124
|
<BottomSheetModalProvider>{children}</BottomSheetModalProvider>
|
|
@@ -142,11 +126,7 @@ export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
|
142
126
|
);
|
|
143
127
|
}
|
|
144
128
|
|
|
145
|
-
|
|
146
|
-
* Hook to control TrueSheet instances by name.
|
|
147
|
-
* On web, this uses the TrueSheetContext from TrueSheetProvider.
|
|
148
|
-
*/
|
|
149
|
-
export function useTrueSheet(): TrueSheetContextMethods {
|
|
129
|
+
export function useTrueSheet(): TrueSheetStaticMethods {
|
|
150
130
|
const context = useContext(BottomSheetContext);
|
|
151
131
|
|
|
152
132
|
if (!context) {
|
|
@@ -156,6 +136,7 @@ export function useTrueSheet(): TrueSheetContextMethods {
|
|
|
156
136
|
return {
|
|
157
137
|
present: context.present,
|
|
158
138
|
dismiss: context.dismiss,
|
|
139
|
+
dismissStack: context.dismissStack,
|
|
159
140
|
resize: context.resize,
|
|
160
141
|
dismissAll: context.dismissAll,
|
|
161
142
|
};
|
package/src/index.ts
CHANGED
package/src/mocks/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { createElement, isValidElement, type ReactNode } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import type { TrueSheetProps
|
|
4
|
+
import type { TrueSheetProps } from '../TrueSheet.types';
|
|
5
|
+
import type { TrueSheetStaticMethods } from '../TrueSheetProvider';
|
|
5
6
|
|
|
6
7
|
interface TrueSheetState {
|
|
7
8
|
shouldRenderNativeView: boolean;
|
|
@@ -11,13 +12,11 @@ interface TrueSheetState {
|
|
|
11
12
|
* Mock TrueSheet component for testing.
|
|
12
13
|
* Import from '@lodev09/react-native-true-sheet/mock' in your test setup.
|
|
13
14
|
*/
|
|
14
|
-
export class TrueSheet
|
|
15
|
-
extends React.Component<TrueSheetProps, TrueSheetState>
|
|
16
|
-
implements TrueSheetRef
|
|
17
|
-
{
|
|
15
|
+
export class TrueSheet extends React.Component<TrueSheetProps, TrueSheetState> {
|
|
18
16
|
static instances: Record<string, TrueSheet> = {};
|
|
19
17
|
|
|
20
18
|
static dismiss = jest.fn((_name: string, _animated?: boolean) => Promise.resolve());
|
|
19
|
+
static dismissStack = jest.fn((_name: string, _animated?: boolean) => Promise.resolve());
|
|
21
20
|
static present = jest.fn((_name: string, _index?: number, _animated?: boolean) =>
|
|
22
21
|
Promise.resolve()
|
|
23
22
|
);
|
|
@@ -25,6 +24,7 @@ export class TrueSheet
|
|
|
25
24
|
static dismissAll = jest.fn((_animated?: boolean) => Promise.resolve());
|
|
26
25
|
|
|
27
26
|
dismiss = jest.fn((_animated?: boolean) => Promise.resolve());
|
|
27
|
+
dismissStack = jest.fn((_animated?: boolean) => Promise.resolve());
|
|
28
28
|
present = jest.fn((_index?: number, _animated?: boolean) => Promise.resolve());
|
|
29
29
|
resize = jest.fn((_index: number) => Promise.resolve());
|
|
30
30
|
|
|
@@ -70,10 +70,11 @@ export function TrueSheetProvider({ children }: { children: React.ReactNode }) {
|
|
|
70
70
|
/**
|
|
71
71
|
* Mock useTrueSheet hook for testing.
|
|
72
72
|
*/
|
|
73
|
-
export function useTrueSheet():
|
|
73
|
+
export function useTrueSheet(): TrueSheetStaticMethods {
|
|
74
74
|
return {
|
|
75
75
|
present: TrueSheet.present,
|
|
76
76
|
dismiss: TrueSheet.dismiss,
|
|
77
|
+
dismissStack: TrueSheet.dismissStack,
|
|
77
78
|
resize: TrueSheet.resize,
|
|
78
79
|
dismissAll: TrueSheet.dismissAll,
|
|
79
80
|
};
|
package/src/mocks/reanimated.ts
CHANGED
|
@@ -2,7 +2,7 @@ import React, { createElement, isValidElement, type ReactNode } from 'react';
|
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import type { SharedValue } from 'react-native-reanimated';
|
|
4
4
|
|
|
5
|
-
import type { TrueSheetProps,
|
|
5
|
+
import type { TrueSheetProps, PositionChangeEventPayload } from '../TrueSheet.types';
|
|
6
6
|
|
|
7
7
|
interface TrueSheetState {
|
|
8
8
|
shouldRenderNativeView: boolean;
|
|
@@ -28,19 +28,18 @@ const createMockSharedValue = <T>(initialValue: T): SharedValue<T> =>
|
|
|
28
28
|
* Mock ReanimatedTrueSheet component for testing.
|
|
29
29
|
* Import from '@lodev09/react-native-true-sheet/reanimated/mock' in your test setup.
|
|
30
30
|
*/
|
|
31
|
-
export class ReanimatedTrueSheet
|
|
32
|
-
extends React.Component<TrueSheetProps, TrueSheetState>
|
|
33
|
-
implements TrueSheetRef
|
|
34
|
-
{
|
|
31
|
+
export class ReanimatedTrueSheet extends React.Component<TrueSheetProps, TrueSheetState> {
|
|
35
32
|
static instances: Record<string, ReanimatedTrueSheet> = {};
|
|
36
33
|
|
|
37
34
|
static dismiss = jest.fn((_name: string, _animated?: boolean) => Promise.resolve());
|
|
35
|
+
static dismissStack = jest.fn((_name: string, _animated?: boolean) => Promise.resolve());
|
|
38
36
|
static present = jest.fn((_name: string, _index?: number, _animated?: boolean) =>
|
|
39
37
|
Promise.resolve()
|
|
40
38
|
);
|
|
41
39
|
static resize = jest.fn((_name: string, _index: number) => Promise.resolve());
|
|
42
40
|
|
|
43
41
|
dismiss = jest.fn((_animated?: boolean) => Promise.resolve());
|
|
42
|
+
dismissStack = jest.fn((_animated?: boolean) => Promise.resolve());
|
|
44
43
|
present = jest.fn((_index?: number, _animated?: boolean) => Promise.resolve());
|
|
45
44
|
resize = jest.fn((_index: number) => Promise.resolve());
|
|
46
45
|
|