@lodev09/react-native-true-sheet 3.4.0-beta.0 → 3.4.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.
@@ -368,8 +368,8 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
368
368
  isSheetUpdatePending = true
369
369
  viewController.post {
370
370
  isSheetUpdatePending = false
371
- viewController.setupSheetDetents()
372
- viewController.positionFooter()
371
+ viewController.setupSheetDetentsForSizeChange()
372
+ TrueSheetDialogObserver.onSheetSizeChanged(this)
373
373
  }
374
374
  }
375
375
 
@@ -384,9 +384,7 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
384
384
  }
385
385
 
386
386
  override fun containerViewFooterDidChangeSize(width: Int, height: Int) {
387
- if (viewController.isPresented) {
388
- viewController.positionFooter()
389
- }
387
+ viewController.positionFooter()
390
388
  }
391
389
 
392
390
  companion object {
@@ -76,6 +76,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
76
76
  // Animation durations from res/anim/true_sheet_slide_in.xml and true_sheet_slide_out.xml
77
77
  private const val PRESENT_ANIMATION_DURATION = 250L
78
78
  private const val DISMISS_ANIMATION_DURATION = 150L
79
+ private const val TRANSLATE_ANIMATION_DURATION = 100L
79
80
  }
80
81
 
81
82
  // ====================================================================
@@ -408,6 +409,8 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
408
409
  isDialogVisible = false
409
410
  dialog?.window?.setWindowAnimations(com.lodev09.truesheet.R.style.TrueSheetFadeOutAnimation)
410
411
  dialog?.window?.decorView?.visibility = INVISIBLE
412
+ dimView?.visibility = INVISIBLE
413
+ parentDimView?.visibility = INVISIBLE
411
414
  wasHiddenByModal = true
412
415
  }
413
416
  },
@@ -416,6 +419,8 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
416
419
  if (isPresented && wasHiddenByModal) {
417
420
  isDialogVisible = true
418
421
  dialog?.window?.decorView?.visibility = VISIBLE
422
+ dimView?.visibility = VISIBLE
423
+ parentDimView?.visibility = VISIBLE
419
424
  // Restore animation after visibility change to avoid slide animation
420
425
  sheetContainer?.post {
421
426
  dialog?.window?.setWindowAnimations(windowAnimation)
@@ -478,11 +483,10 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
478
483
  /** Translates the sheet when stacking. Pass 0 to reset. */
479
484
  fun translateDialog(translationY: Int) {
480
485
  val bottomSheet = bottomSheetView ?: return
481
- val duration = if (translationY > 0) PRESENT_ANIMATION_DURATION else DISMISS_ANIMATION_DURATION
482
486
 
483
487
  bottomSheet.animate()
484
488
  .translationY(translationY.toFloat())
485
- .setDuration(duration)
489
+ .setDuration(TRANSLATE_ANIMATION_DURATION)
486
490
  .setUpdateListener {
487
491
  val effectiveTop = bottomSheet.top + bottomSheet.translationY.toInt()
488
492
  emitChangePositionDelegate(effectiveTop)
@@ -589,6 +593,11 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
589
593
  }
590
594
  }
591
595
 
596
+ fun setupSheetDetentsForSizeChange() {
597
+ setupSheetDetents()
598
+ positionFooter()
599
+ }
600
+
592
601
  fun setupGrabber() {
593
602
  val bottomSheet = bottomSheetView ?: return
594
603
 
@@ -20,18 +20,8 @@ object TrueSheetDialogObserver {
20
20
  val parentSheet = presentedSheetStack.lastOrNull()
21
21
  ?.takeIf { it.viewController.isPresented && it.viewController.isDialogVisible }
22
22
 
23
- // Translate parent sheets down to match the new sheet's position
24
- val newSheetTop = sheetView.viewController.getExpectedSheetTop(detentIndex)
25
- for (sheet in presentedSheetStack) {
26
- if (!sheet.viewController.isDialogVisible) continue
27
- if (sheet.viewController.isExpanded) continue
28
-
29
- val sheetTop = sheet.viewController.currentSheetTop
30
- if (sheetTop < newSheetTop) {
31
- val translationY = newSheetTop - sheetTop
32
- sheet.viewController.translateDialog(translationY)
33
- }
34
- }
23
+ val childSheetTop = sheetView.viewController.getExpectedSheetTop(detentIndex)
24
+ updateParentTranslations(childSheetTop)
35
25
 
36
26
  if (!presentedSheetStack.contains(sheetView)) {
37
27
  presentedSheetStack.add(sheetView)
@@ -43,7 +33,7 @@ object TrueSheetDialogObserver {
43
33
 
44
34
  /**
45
35
  * Called when a sheet has been dismissed.
46
- * Shows the parent sheet if this sheet was stacked on it.
36
+ * Resets parent sheet translation if this sheet was stacked on it.
47
37
  */
48
38
  @JvmStatic
49
39
  fun onSheetDidDismiss(sheetView: TrueSheetView, hadParent: Boolean) {
@@ -55,6 +45,27 @@ object TrueSheetDialogObserver {
55
45
  }
56
46
  }
57
47
 
48
+ /**
49
+ * Called when a presented sheet's size changes (e.g., after setupSheetDetents).
50
+ * Updates parent sheet translations to match the new sheet position.
51
+ */
52
+ @JvmStatic
53
+ fun onSheetSizeChanged(sheetView: TrueSheetView) {
54
+ synchronized(presentedSheetStack) {
55
+ val index = presentedSheetStack.indexOf(sheetView)
56
+ if (index <= 0) return
57
+
58
+ // Post to ensure layout is complete before reading position
59
+ sheetView.viewController.post {
60
+ val childMinSheetTop = sheetView.viewController.getExpectedSheetTop(0)
61
+ val childCurrentSheetTop = sheetView.viewController.getExpectedSheetTop(sheetView.viewController.currentDetentIndex)
62
+ // Cap to minimum detent position
63
+ val childSheetTop = maxOf(childMinSheetTop, childCurrentSheetTop)
64
+ updateParentTranslations(childSheetTop, untilIndex = index)
65
+ }
66
+ }
67
+ }
68
+
58
69
  /**
59
70
  * Returns all sheets presented on top of the given sheet (children/descendants).
60
71
  * Returns them in reverse order (top-most first) for proper dismissal.
@@ -81,4 +92,25 @@ object TrueSheetDialogObserver {
81
92
  presentedSheetStack.clear()
82
93
  }
83
94
  }
95
+
96
+ /**
97
+ * Translates parent sheets down to match the child sheet's position.
98
+ * @param childSheetTop The top position of the child sheet
99
+ * @param untilIndex If specified, only update sheets up to this index (exclusive)
100
+ */
101
+ private fun updateParentTranslations(childSheetTop: Int, untilIndex: Int = presentedSheetStack.size) {
102
+ for (i in 0 until untilIndex) {
103
+ val parentSheet = presentedSheetStack[i]
104
+ if (!parentSheet.viewController.isDialogVisible) continue
105
+ if (parentSheet.viewController.isExpanded) continue
106
+
107
+ val parentSheetTop = parentSheet.viewController.getExpectedSheetTop(parentSheet.viewController.currentDetentIndex)
108
+ if (parentSheetTop < childSheetTop) {
109
+ val translationY = childSheetTop - parentSheetTop
110
+ parentSheet.viewController.translateDialog(translationY)
111
+ } else {
112
+ parentSheet.viewController.translateDialog(0)
113
+ }
114
+ }
115
+ }
84
116
  }
@@ -403,10 +403,7 @@ using namespace facebook::react;
403
403
 
404
404
  dispatch_async(dispatch_get_main_queue(), ^{
405
405
  self->_isSheetUpdatePending = NO;
406
-
407
- [self->_controller.sheetPresentationController animateChanges:^{
408
- [self->_controller setupSheetDetentsForSizeChange];
409
- }];
406
+ [self->_controller setupSheetDetentsForSizeChange];
410
407
  });
411
408
  }
412
409
 
@@ -594,8 +594,10 @@
594
594
  #pragma mark - Sheet Configuration
595
595
 
596
596
  - (void)setupSheetDetentsForSizeChange {
597
- _pendingContentSizeChange = YES;
598
- [self setupSheetDetents];
597
+ [self.sheetPresentationController animateChanges:^{
598
+ _pendingContentSizeChange = YES;
599
+ [self setupSheetDetents];
600
+ }];
599
601
  }
600
602
 
601
603
  - (void)setupSheetDetentsForDetentsChange {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodev09/react-native-true-sheet",
3
- "version": "3.4.0-beta.0",
3
+ "version": "3.4.0-beta.1",
4
4
  "description": "The true native bottom sheet experience for your React Native Apps.",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",