@lodev09/react-native-true-sheet 3.11.10 → 4.0.0-beta.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 +6 -5
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +23 -2
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +116 -26
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +7 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +48 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterViewManager.kt +7 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +28 -12
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +99 -34
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +9 -5
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +12 -3
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +33 -4
- package/android/src/main/jni/TrueSheetSpec.h +2 -0
- package/android/src/main/jni/TrueSheetStateUpdater.cpp +96 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +24 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +43 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +28 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +11 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +37 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +24 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +56 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +28 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +11 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +41 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +18 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +16 -0
- package/ios/TrueSheetContainerView.h +12 -10
- package/ios/TrueSheetContainerView.mm +11 -29
- package/ios/TrueSheetContentView.h +22 -7
- package/ios/TrueSheetContentView.mm +143 -41
- package/ios/TrueSheetFooterView.h +12 -2
- package/ios/TrueSheetFooterView.mm +74 -71
- package/ios/TrueSheetHeaderView.mm +0 -1
- package/ios/TrueSheetView.mm +60 -27
- package/ios/TrueSheetViewController.h +9 -0
- package/ios/TrueSheetViewController.mm +288 -122
- package/ios/core/TrueSheetDetentCalculator.h +9 -0
- package/ios/core/TrueSheetDetentCalculator.mm +13 -4
- package/ios/tvos/TrueSheetStubs.mm +2 -0
- package/lib/module/TrueSheet.js +32 -13
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +262 -38
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +8 -1
- package/lib/module/web/vaul/index.js +17 -6
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +35 -11
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +5 -1
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +1 -1
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +8 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/package.json +10 -10
- package/react-native.config.js +5 -1
- package/src/TrueSheet.tsx +45 -14
- package/src/TrueSheet.types.ts +38 -12
- package/src/TrueSheet.web.tsx +314 -44
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
- package/src/fabric/TrueSheetViewNativeComponent.ts +8 -1
- package/src/navigation/types.ts +3 -1
- package/src/web/vaul/index.tsx +23 -5
- package/ios/utils/LayoutUtil.h +0 -77
- package/ios/utils/LayoutUtil.mm +0 -106
package/ios/TrueSheetView.mm
CHANGED
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
#import "events/TrueSheetFocusEvents.h"
|
|
20
20
|
#import "events/TrueSheetLifecycleEvents.h"
|
|
21
21
|
#import "events/TrueSheetStateEvents.h"
|
|
22
|
-
#import "utils/
|
|
22
|
+
#import "utils/WindowUtil.h"
|
|
23
23
|
|
|
24
24
|
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
25
25
|
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
26
26
|
#import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
|
|
27
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetInsets.h>
|
|
27
28
|
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h>
|
|
28
29
|
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h>
|
|
29
30
|
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewState.h>
|
|
@@ -33,7 +34,6 @@
|
|
|
33
34
|
#import <React/RCTLog.h>
|
|
34
35
|
#import <React/RCTSurfaceTouchHandler.h>
|
|
35
36
|
#import <React/RCTUtils.h>
|
|
36
|
-
#import <cxxreact/ReactNativeVersion.h>
|
|
37
37
|
#import <react/renderer/core/State.h>
|
|
38
38
|
|
|
39
39
|
using namespace facebook::react;
|
|
@@ -52,8 +52,8 @@ using namespace facebook::react;
|
|
|
52
52
|
CGSize _lastStateSize;
|
|
53
53
|
NSInteger _initialDetentIndex;
|
|
54
54
|
TrueSheetViewInsetAdjustment _insetAdjustment;
|
|
55
|
-
BOOL _scrollable;
|
|
56
55
|
ScrollableOptions *_scrollableOptions;
|
|
56
|
+
BOOL _hasAutoDetent;
|
|
57
57
|
BOOL _initialDetentAnimated;
|
|
58
58
|
BOOL _isSheetUpdatePending;
|
|
59
59
|
BOOL _pendingLayoutUpdate;
|
|
@@ -86,7 +86,6 @@ using namespace facebook::react;
|
|
|
86
86
|
_lastStateSize = CGSizeZero;
|
|
87
87
|
_initialDetentIndex = -1;
|
|
88
88
|
_initialDetentAnimated = YES;
|
|
89
|
-
_scrollable = NO;
|
|
90
89
|
_isSheetUpdatePending = NO;
|
|
91
90
|
|
|
92
91
|
_screensEventObserver = [[RNScreensEventObserver alloc] init];
|
|
@@ -164,8 +163,12 @@ using namespace facebook::react;
|
|
|
164
163
|
|
|
165
164
|
// Detents (-1 represents "auto")
|
|
166
165
|
NSMutableArray *detents = [NSMutableArray new];
|
|
166
|
+
_hasAutoDetent = NO;
|
|
167
167
|
for (const auto &detent : newProps.detents) {
|
|
168
168
|
[detents addObject:@(detent)];
|
|
169
|
+
if (detent == -1) {
|
|
170
|
+
_hasAutoDetent = YES;
|
|
171
|
+
}
|
|
169
172
|
}
|
|
170
173
|
|
|
171
174
|
if (oldProps) {
|
|
@@ -244,7 +247,6 @@ using namespace facebook::react;
|
|
|
244
247
|
|
|
245
248
|
_initialDetentIndex = newProps.initialDetentIndex;
|
|
246
249
|
_initialDetentAnimated = newProps.initialDetentAnimated;
|
|
247
|
-
_scrollable = newProps.scrollable;
|
|
248
250
|
|
|
249
251
|
const auto &scrollableOpts = newProps.scrollableOptions;
|
|
250
252
|
BOOL scrollingExpandsSheet = scrollableOpts.scrollingExpandsSheet;
|
|
@@ -267,6 +269,9 @@ using namespace facebook::react;
|
|
|
267
269
|
|
|
268
270
|
_controller.scrollingExpandsSheet = scrollingExpandsSheet;
|
|
269
271
|
|
|
272
|
+
_controller.absoluteHeader = newProps.headerOptions.position == TrueSheetViewPosition::Absolute;
|
|
273
|
+
_controller.absoluteFooter = newProps.footerOptions.footerPosition == TrueSheetViewFooterPosition::Absolute;
|
|
274
|
+
|
|
270
275
|
CGFloat footerKeyboardOffset = newProps.footerOptions.keyboardOffset;
|
|
271
276
|
if (_controller.footerKeyboardOffset != footerKeyboardOffset) {
|
|
272
277
|
_controller.footerKeyboardOffset = footerKeyboardOffset;
|
|
@@ -282,9 +287,16 @@ using namespace facebook::react;
|
|
|
282
287
|
- (void)updateState:(const State::Shared &)state oldState:(const State::Shared &)oldState {
|
|
283
288
|
_state = std::static_pointer_cast<TrueSheetViewShadowNode::ConcreteState const>(state);
|
|
284
289
|
|
|
285
|
-
if (_controller) {
|
|
286
|
-
|
|
287
|
-
|
|
290
|
+
if (_controller && !_controller.isStackedBehindChild) {
|
|
291
|
+
CGSize size = _controller.view.frame.size;
|
|
292
|
+
if (size.width < 1 || size.height < 1) {
|
|
293
|
+
// Pre-present the controller has no layout yet. Seed with screen
|
|
294
|
+
// dimensions so content (e.g. a FlatList viewport) can lay out and
|
|
295
|
+
// measure before the sheet presents (parity with Android).
|
|
296
|
+
UIWindow *window = [WindowUtil keyWindow];
|
|
297
|
+
size = window ? window.bounds.size : UIScreen.mainScreen.bounds.size;
|
|
298
|
+
}
|
|
299
|
+
[self viewControllerDidChangeSize:size];
|
|
288
300
|
}
|
|
289
301
|
}
|
|
290
302
|
|
|
@@ -304,13 +316,10 @@ using namespace facebook::react;
|
|
|
304
316
|
stateData.containerWidth = static_cast<float>(size.width);
|
|
305
317
|
stateData.containerHeight = static_cast<float>(size.height);
|
|
306
318
|
|
|
307
|
-
|
|
308
|
-
//
|
|
309
|
-
//
|
|
319
|
+
// RN 0.82+ processes immediate state updates in the same layout pass, so Yoga
|
|
320
|
+
// resizes the container synchronously with the sheet (e.g. inside UIKit's
|
|
321
|
+
// animation block during detent transitions).
|
|
310
322
|
_state->updateState(std::move(stateData), facebook::react::EventQueue::UpdateMode::unstable_Immediate);
|
|
311
|
-
#else
|
|
312
|
-
_state->updateState(std::move(stateData));
|
|
313
|
-
#endif
|
|
314
323
|
}
|
|
315
324
|
|
|
316
325
|
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask {
|
|
@@ -355,7 +364,6 @@ using namespace facebook::react;
|
|
|
355
364
|
|
|
356
365
|
_containerView.delegate = nil;
|
|
357
366
|
[_touchHandler detachFromView:_containerView];
|
|
358
|
-
[LayoutUtil unpinView:_containerView fromParentView:nil];
|
|
359
367
|
[_containerView removeFromSuperview];
|
|
360
368
|
|
|
361
369
|
_containerView = nil;
|
|
@@ -380,7 +388,6 @@ using namespace facebook::react;
|
|
|
380
388
|
|
|
381
389
|
[_touchHandler attachToView:_containerView];
|
|
382
390
|
[_controller.view addSubview:_containerView];
|
|
383
|
-
[LayoutUtil pinView:_containerView toParentView:_controller.view edges:UIRectEdgeAll];
|
|
384
391
|
[_controller.view bringSubviewToFront:_containerView];
|
|
385
392
|
_containerView.accessibilityViewIsModal = YES;
|
|
386
393
|
_controller.accessibilityContentView = _containerView;
|
|
@@ -463,11 +470,24 @@ using namespace facebook::react;
|
|
|
463
470
|
[_controller setupAnchorViewInView:presentingViewController.view];
|
|
464
471
|
[_controller setupSheetSizing];
|
|
465
472
|
[_controller setupSheetProps];
|
|
466
|
-
[_controller setupSheetDetents];
|
|
467
|
-
[_controller setupActiveDetentWithIndex:index];
|
|
468
473
|
|
|
474
|
+
// Pin before measuring so a first-time pin doesn't shift sizes mid-animation.
|
|
469
475
|
[self setupScrollable];
|
|
470
476
|
|
|
477
|
+
// Measure synchronously so the presentation starts at the right height —
|
|
478
|
+
// async size reports would otherwise land mid-animation and force a
|
|
479
|
+
// detent retarget that snaps the presentation stack.
|
|
480
|
+
if (_containerView) {
|
|
481
|
+
_controller.contentHeight = @([_containerView contentHeight]);
|
|
482
|
+
_controller.headerHeight = @([_containerView headerHeight]);
|
|
483
|
+
_controller.footerHeight = @([_containerView footerHeight]);
|
|
484
|
+
_controller.peekContentHeight = @([_containerView peekContentHeight]);
|
|
485
|
+
}
|
|
486
|
+
_pendingSizeChange = NO;
|
|
487
|
+
|
|
488
|
+
[_controller setupSheetDetents];
|
|
489
|
+
[_controller setupActiveDetentWithIndex:index];
|
|
490
|
+
|
|
471
491
|
[_screensEventObserver capturePresenterScreenFromView:self];
|
|
472
492
|
[_screensEventObserver startObservingWithState:_state.get()->getData()];
|
|
473
493
|
|
|
@@ -563,19 +583,28 @@ using namespace facebook::react;
|
|
|
563
583
|
* Debounced sheet update to handle rapid content/header size changes.
|
|
564
584
|
*/
|
|
565
585
|
- (void)setupSheetDetentsForSizeChange {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
586
|
+
// Retargeting the in-flight presentation makes UIKit snap the whole stack
|
|
587
|
+
// (including the sheet behind) instead of animating. Defer to didPresent —
|
|
588
|
+
// presentAtIndex measured synchronously, so this is usually a no-op.
|
|
569
589
|
if (_controller.isBeingPresented) {
|
|
570
590
|
_pendingSizeChange = YES;
|
|
571
591
|
return;
|
|
572
592
|
}
|
|
573
593
|
|
|
594
|
+
// Not presented: presentAtIndex measures at present time.
|
|
595
|
+
// Dismissing: the sheet is going away — touching detents perturbs the
|
|
596
|
+
// presentation stack, visibly glitching the sheet behind.
|
|
597
|
+
if (!_controller.isPresented || _controller.isBeingDismissed)
|
|
598
|
+
return;
|
|
599
|
+
|
|
600
|
+
if (_isSheetUpdatePending)
|
|
601
|
+
return;
|
|
602
|
+
|
|
574
603
|
_isSheetUpdatePending = YES;
|
|
575
604
|
|
|
576
605
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
577
606
|
self->_isSheetUpdatePending = NO;
|
|
578
|
-
if (!self->_containerView)
|
|
607
|
+
if (!self->_containerView || self->_controller.isBeingDismissed)
|
|
579
608
|
return;
|
|
580
609
|
|
|
581
610
|
// Refresh here (not just on peek size events) since the peek's offset
|
|
@@ -684,10 +713,7 @@ using namespace facebook::react;
|
|
|
684
713
|
}
|
|
685
714
|
|
|
686
715
|
- (void)viewControllerDidChangeSize:(CGSize)size {
|
|
687
|
-
|
|
688
|
-
CGSize effectiveSize = CGSizeMake(size.width, _controller.screenHeight);
|
|
689
|
-
|
|
690
|
-
[self updateStateWithSize:effectiveSize];
|
|
716
|
+
[self updateStateWithSize:size];
|
|
691
717
|
}
|
|
692
718
|
|
|
693
719
|
- (void)viewControllerWillFocus {
|
|
@@ -755,10 +781,17 @@ using namespace facebook::react;
|
|
|
755
781
|
if (!_containerView)
|
|
756
782
|
return;
|
|
757
783
|
|
|
758
|
-
_containerView.scrollableEnabled = _scrollable;
|
|
759
784
|
_containerView.insetAdjustment = _insetAdjustment;
|
|
760
785
|
_containerView.scrollableOptions = _scrollableOptions;
|
|
786
|
+
_containerView.hasAutoDetent = _hasAutoDetent;
|
|
787
|
+
_containerView.footerBottomInset = _controller.footerBottomInset;
|
|
761
788
|
[_containerView setupScrollable];
|
|
789
|
+
|
|
790
|
+
// Publish the inset so a footer set later (e.g. navigation setOptions) is
|
|
791
|
+
// padded on its very first layout instead of resizing the sheet twice.
|
|
792
|
+
if (_insetAdjustment == TrueSheetViewInsetAdjustment::Automatic) {
|
|
793
|
+
TrueSheetInsets::setBottomSafeArea(_controller.footerBottomInset);
|
|
794
|
+
}
|
|
762
795
|
}
|
|
763
796
|
|
|
764
797
|
- (void)applySheetPropsUpdate {
|
|
@@ -57,7 +57,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
57
57
|
@property (nonatomic, strong, nullable) NSNumber *maxContentWidth;
|
|
58
58
|
@property (nonatomic, strong, nullable) NSNumber *contentHeight;
|
|
59
59
|
@property (nonatomic, strong, nullable) NSNumber *headerHeight;
|
|
60
|
+
@property (nonatomic, assign) BOOL absoluteHeader;
|
|
60
61
|
@property (nonatomic, strong, nullable) NSNumber *footerHeight;
|
|
62
|
+
@property (nonatomic, assign) BOOL absoluteFooter;
|
|
61
63
|
@property (nonatomic, strong, nullable) NSNumber *peekContentHeight;
|
|
62
64
|
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
|
|
63
65
|
@property (nonatomic, strong, nullable) NSNumber *cornerRadius;
|
|
@@ -86,10 +88,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
86
88
|
*/
|
|
87
89
|
@property (nonatomic, assign) BOOL keyboardSheetGrown;
|
|
88
90
|
@property (nonatomic, readonly) BOOL isTopmostPresentedController;
|
|
91
|
+
@property (nonatomic, readonly) BOOL isStackedBehindChild;
|
|
89
92
|
@property (nonatomic, weak, nullable) UIView *accessibilityContentView;
|
|
90
93
|
|
|
91
94
|
@property (nonatomic, readonly) CGFloat screenHeight;
|
|
92
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Bottom safe-area inset the footer absorbs as padding — the footer
|
|
98
|
+
* owns the sheet's bottom edge, so its background fills the inset.
|
|
99
|
+
*/
|
|
100
|
+
@property (nonatomic, readonly) CGFloat footerBottomInset;
|
|
101
|
+
|
|
93
102
|
- (void)setupAccessibilityContainer;
|
|
94
103
|
- (void)applyActiveDetent;
|
|
95
104
|
- (void)setupActiveDetentWithIndex:(NSInteger)index;
|