@lodev09/react-native-true-sheet 3.6.6 → 3.6.8

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.
@@ -2,6 +2,7 @@ package com.lodev09.truesheet
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.view.View
5
+ import android.view.ViewGroup
5
6
  import android.view.ViewStructure
6
7
  import android.view.accessibility.AccessibilityEvent
7
8
  import androidx.annotation.UiThread
@@ -64,6 +65,9 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
64
65
  // Debounce flag to coalesce rapid layout changes into a single sheet update
65
66
  private var isSheetUpdatePending: Boolean = false
66
67
 
68
+ // Root container for the coordinator layout (activity or Modal dialog content view)
69
+ private var rootContainerView: ViewGroup? = null
70
+
67
71
  // ==================== Initialization ====================
68
72
 
69
73
  init {
@@ -154,13 +158,16 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
154
158
 
155
159
  fun onDropInstance() {
156
160
  reactContext.removeLifecycleEventListener(this)
157
- TrueSheetModule.unregisterView(id)
158
- TrueSheetStackManager.removeSheet(this)
159
161
 
160
162
  if (viewController.isPresented) {
161
163
  viewController.dismiss(animated = false)
162
164
  }
165
+
166
+ TrueSheetModule.unregisterView(id)
167
+ TrueSheetStackManager.removeSheet(this)
168
+
163
169
  viewController.delegate = null
170
+ didInitiallyPresent = false
164
171
  }
165
172
 
166
173
  /**
@@ -262,6 +269,10 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
262
269
  @UiThread
263
270
  fun present(detentIndex: Int, animated: Boolean = true, promiseCallback: () -> Unit) {
264
271
  if (!viewController.isPresented) {
272
+ // Attach coordinator to the root container
273
+ rootContainerView = findRootContainerView()
274
+ viewController.coordinatorLayout?.let { rootContainerView?.addView(it) }
275
+
265
276
  // Register with observer to track sheet stack hierarchy
266
277
  viewController.parentSheetView = TrueSheetStackManager.onSheetWillPresent(this, detentIndex)
267
278
  }
@@ -387,6 +398,10 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
387
398
  }
388
399
 
389
400
  override fun viewControllerDidDismiss(hadParent: Boolean) {
401
+ // Detach coordinator from the root container view
402
+ viewController.coordinatorLayout?.let { rootContainerView?.removeView(it) }
403
+ rootContainerView = null
404
+
390
405
  val surfaceId = UIManagerHelper.getSurfaceId(this)
391
406
  eventDispatcher?.dispatchEvent(DidDismissEvent(surfaceId, id))
392
407
 
@@ -461,4 +476,25 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
461
476
  // Footer changes don't affect detents, only reposition it
462
477
  viewController.positionFooter()
463
478
  }
479
+
480
+ // ==================== Private Helpers ====================
481
+
482
+ /**
483
+ * Find the root container view for presenting the sheet.
484
+ * This traverses up the view hierarchy to find the content view (android.R.id.content)
485
+ * of whichever window this view is in - whether that's the activity's window or a
486
+ * Modal's dialog window.
487
+ */
488
+ private fun findRootContainerView(): ViewGroup? {
489
+ var current: android.view.ViewParent? = parent
490
+
491
+ while (current != null) {
492
+ if (current is ViewGroup && current.id == android.R.id.content) {
493
+ return current
494
+ }
495
+ current = current.parent
496
+ }
497
+
498
+ return reactContext.currentActivity?.findViewById(android.R.id.content)
499
+ }
464
500
  }
@@ -110,7 +110,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
110
110
 
111
111
  // CoordinatorLayout components (replaces DialogFragment)
112
112
  internal var sheetView: TrueSheetBottomSheetView? = null
113
- private var coordinatorLayout: TrueSheetCoordinatorLayout? = null
113
+ internal var coordinatorLayout: TrueSheetCoordinatorLayout? = null
114
114
  private var dimView: TrueSheetDimView? = null
115
115
  private var parentDimView: TrueSheetDimView? = null
116
116
 
@@ -303,9 +303,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
303
303
  cleanupBackCallback()
304
304
  sheetView?.animate()?.cancel()
305
305
 
306
- // Remove from activity
307
- removeFromActivity()
308
-
309
306
  // Cleanup dim views
310
307
  dimView?.detach()
311
308
  dimView = null
@@ -330,12 +327,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
330
327
  shouldAnimatePresent = true
331
328
  }
332
329
 
333
- private fun removeFromActivity() {
334
- val coordinator = coordinatorLayout ?: return
335
- val contentView = reactContext.currentActivity?.findViewById<ViewGroup>(android.R.id.content)
336
- contentView?.removeView(coordinator)
337
- }
338
-
339
330
  // =============================================================================
340
331
  // MARK: - Back Button Handling
341
332
  // =============================================================================
@@ -603,15 +594,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
603
594
  // Setup sheet in coordinator layout
604
595
  setupSheetInCoordinator(coordinator, sheet)
605
596
 
606
- // Add coordinator to activity
607
- val activity = reactContext.currentActivity ?: run {
608
- RNLog.w(reactContext, "TrueSheet: No activity available for presentation.")
609
- return
610
- }
611
-
612
- val contentView = activity.findViewById<ViewGroup>(android.R.id.content)
613
- contentView?.addView(coordinator)
614
-
615
597
  emitWillPresentEvents()
616
598
 
617
599
  setupSheetDetents()
@@ -22,6 +22,7 @@ using namespace facebook::react;
22
22
  CGFloat _lastHeight;
23
23
  BOOL _didInitialLayout;
24
24
  NSLayoutConstraint *_bottomConstraint;
25
+ CGFloat _currentKeyboardOffset;
25
26
  }
26
27
 
27
28
  + (ComponentDescriptorProvider)componentDescriptorProvider {
@@ -39,6 +40,7 @@ using namespace facebook::react;
39
40
  _lastHeight = 0;
40
41
  _didInitialLayout = NO;
41
42
  _bottomConstraint = nil;
43
+ _currentKeyboardOffset = 0;
42
44
  }
43
45
  return self;
44
46
  }
@@ -59,8 +61,9 @@ using namespace facebook::react;
59
61
  [self.leadingAnchor constraintEqualToAnchor:parentView.leadingAnchor].active = YES;
60
62
  [self.trailingAnchor constraintEqualToAnchor:parentView.trailingAnchor].active = YES;
61
63
 
62
- // Store bottom constraint for keyboard adjustment
63
- _bottomConstraint = [self.bottomAnchor constraintEqualToAnchor:parentView.bottomAnchor];
64
+ // Store bottom constraint for keyboard adjustment, preserving current keyboard offset
65
+ _bottomConstraint = [self.bottomAnchor constraintEqualToAnchor:parentView.bottomAnchor
66
+ constant:-_currentKeyboardOffset];
64
67
  _bottomConstraint.active = YES;
65
68
 
66
69
  // Apply height constraint
@@ -109,6 +112,7 @@ using namespace facebook::react;
109
112
  _lastHeight = 0;
110
113
  _didInitialLayout = NO;
111
114
  _bottomConstraint = nil;
115
+ _currentKeyboardOffset = 0;
112
116
  }
113
117
 
114
118
  #pragma mark - Keyboard Handling
@@ -163,6 +167,9 @@ using namespace facebook::react;
163
167
  // Cap to ensure we don't go negative
164
168
  CGFloat bottomOffset = MAX(0, keyboardHeight);
165
169
 
170
+ // Store the current keyboard offset so it persists through constraint recreation
171
+ _currentKeyboardOffset = bottomOffset;
172
+
166
173
  [UIView animateWithDuration:duration
167
174
  delay:0
168
175
  options:curve | UIViewAnimationOptionBeginFromCurrentState
@@ -258,13 +258,14 @@ using namespace facebook::react;
258
258
  - (void)prepareForRecycle {
259
259
  [super prepareForRecycle];
260
260
 
261
- _lastStateSize = CGSizeZero;
262
-
263
261
  if (_controller && _controller.presentingViewController) {
264
262
  [_controller dismissViewControllerAnimated:YES completion:nil];
265
263
  }
266
264
 
267
265
  [TrueSheetModule unregisterViewWithTag:@(self.tag)];
266
+
267
+ _lastStateSize = CGSizeZero;
268
+ _didInitiallyPresent = NO;
268
269
  }
269
270
 
270
271
  #pragma mark - Child Component Mounting
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodev09/react-native-true-sheet",
3
- "version": "3.6.6",
3
+ "version": "3.6.8",
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",