@lodev09/react-native-true-sheet 4.0.0-beta.25 → 4.0.0-beta.27

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.
Files changed (39) hide show
  1. package/README.md +1 -0
  2. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +19 -1
  3. package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +1 -1
  4. package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +11 -3
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +31 -10
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +23 -3
  7. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +5 -0
  8. package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +8 -16
  9. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +9 -0
  10. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +0 -8
  11. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +8 -1
  12. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +29 -38
  13. package/android/src/main/jni/TrueSheetStateUpdater.cpp +37 -6
  14. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +6 -2
  15. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +12 -0
  16. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +2 -0
  17. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +8 -2
  18. package/ios/TrueSheetContainerView.h +1 -0
  19. package/ios/TrueSheetContainerView.mm +6 -0
  20. package/ios/TrueSheetContentView.h +1 -0
  21. package/ios/TrueSheetContentView.mm +2 -0
  22. package/ios/TrueSheetFooterView.mm +32 -12
  23. package/ios/TrueSheetView.mm +9 -2
  24. package/ios/TrueSheetViewController.h +12 -0
  25. package/ios/TrueSheetViewController.mm +332 -29
  26. package/ios/core/TrueSheetDetentCalculator.h +11 -0
  27. package/ios/core/TrueSheetDetentCalculator.mm +17 -5
  28. package/ios/core/TrueSheetKeyboardObserver.mm +89 -9
  29. package/lib/module/fabric/TrueSheetViewNativeComponent.ts +6 -0
  30. package/lib/typescript/src/TrueSheet.types.d.ts +31 -0
  31. package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
  32. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +5 -0
  33. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
  34. package/lib/typescript/src/navigation/types.d.ts +1 -1
  35. package/lib/typescript/src/navigation/types.d.ts.map +1 -1
  36. package/package.json +1 -1
  37. package/src/TrueSheet.types.ts +34 -0
  38. package/src/fabric/TrueSheetViewNativeComponent.ts +6 -0
  39. package/src/navigation/types.ts +1 -0
@@ -67,7 +67,7 @@ using namespace facebook::react;
67
67
  return;
68
68
  }
69
69
  _bottomInset = bottomInset;
70
- [self pushBottomInsetState];
70
+ [self pushStateWithMode:EventQueue::UpdateMode::unstable_Immediate];
71
71
  }
72
72
 
73
73
  // Skipped while the keyboard is open — an absolute footer rises above the
@@ -77,22 +77,36 @@ using namespace facebook::react;
77
77
  return;
78
78
  }
79
79
  _keyboardVisible = keyboardVisible;
80
- [self pushBottomInsetState];
80
+ [self pushStateWithMode:EventQueue::UpdateMode::unstable_Immediate];
81
81
  }
82
82
 
83
- - (void)pushBottomInsetState {
83
+ // The keyboard slide is a transform the shadow tree can't see — mirror it so
84
+ // measure() (and Pressability's press region) match where the footer is drawn.
85
+ // Async: no layout reads it.
86
+ - (void)setKeyboardOffset:(CGFloat)keyboardOffset {
87
+ if (_currentKeyboardOffset == keyboardOffset) {
88
+ return;
89
+ }
90
+ _currentKeyboardOffset = keyboardOffset;
91
+ [self pushStateWithMode:EventQueue::UpdateMode::Asynchronous];
92
+ }
93
+
94
+ // Every push carries all fields — RN's EventQueue drops a still-queued update
95
+ // for the same view when the next one is enqueued.
96
+ - (void)pushStateWithMode:(EventQueue::UpdateMode)mode {
84
97
  if (!_state) {
85
98
  return;
86
99
  }
87
100
 
88
101
  TrueSheetFooterViewState newState;
89
102
  newState.bottomInset = _keyboardVisible ? 0 : _bottomInset;
103
+ newState.translateY = -_currentKeyboardOffset;
90
104
  newState.initialized = true;
91
- // Immediate so the inset lands before anything reads the footer's height —
92
- // the async path races the keyboard caret scroll and detent setup, leaving
93
- // them an inset stale (same reason Android bridges through
94
- // TrueSheetStateUpdater).
95
- _state->updateState(std::move(newState), EventQueue::UpdateMode::unstable_Immediate);
105
+ // Inset changes go Immediate so they land before anything reads the
106
+ // footer's height — the async path races the keyboard caret scroll and
107
+ // detent setup, leaving them an inset stale (same reason Android bridges
108
+ // through TrueSheetStateUpdater).
109
+ _state->updateState(std::move(newState), mode);
96
110
  _didPushBottomInset = YES;
97
111
  }
98
112
 
@@ -123,6 +137,11 @@ using namespace facebook::react;
123
137
 
124
138
  - (void)collectAccessibilityElementsFromView:(UIView *)view into:(NSMutableArray *)elements {
125
139
  for (UIView *subview in view.subviews) {
140
+ // Fabric hides `display: none` views instead of unmounting them
141
+ if (subview.hidden) {
142
+ continue;
143
+ }
144
+
126
145
  if (subview.isAccessibilityElement || subview.accessibilityLabel || subview.accessibilityIdentifier) {
127
146
  [elements addObject:subview];
128
147
  } else if (subview.accessibilityElements.count > 0) {
@@ -210,7 +229,7 @@ using namespace facebook::react;
210
229
  [self setKeyboardVisible:YES];
211
230
 
212
231
  CGFloat slide = [self keyboardSlideForHeight:height];
213
- _currentKeyboardOffset = slide;
232
+ [self setKeyboardOffset:slide];
214
233
 
215
234
  [UIView animateWithDuration:duration
216
235
  delay:0
@@ -225,8 +244,9 @@ using namespace facebook::react;
225
244
  }
226
245
 
227
246
  - (void)keyboardWillHide:(NSTimeInterval)duration curve:(UIViewAnimationOptions)curve {
247
+ // Offset first — the visible push replaces it in the queue, one commit
248
+ [self setKeyboardOffset:0];
228
249
  [self setKeyboardVisible:NO];
229
- _currentKeyboardOffset = 0;
230
250
 
231
251
  [UIView animateWithDuration:duration
232
252
  delay:0
@@ -261,8 +281,8 @@ using namespace facebook::react;
261
281
 
262
282
  // avoidKeyboard flipped off mid-keyboard — drop the slide already applied
263
283
  if (![self floatsAboveKeyboard]) {
284
+ [self setKeyboardOffset:0];
264
285
  [self setKeyboardVisible:NO];
265
- _currentKeyboardOffset = 0;
266
286
  self.transform = CGAffineTransformIdentity;
267
287
  return;
268
288
  }
@@ -270,7 +290,7 @@ using namespace facebook::react;
270
290
  [self setKeyboardVisible:YES];
271
291
 
272
292
  CGFloat slide = [self keyboardSlideForHeight:height];
273
- _currentKeyboardOffset = slide;
293
+ [self setKeyboardOffset:slide];
274
294
  self.transform = CGAffineTransformMakeTranslation(0, -slide);
275
295
  }
276
296
 
@@ -284,6 +284,8 @@ using namespace facebook::react;
284
284
 
285
285
  _controller.placement = newProps.placement;
286
286
 
287
+ _controller.foldOptions = newProps.foldOptions;
288
+
287
289
  _controller.grabber = newProps.grabber;
288
290
 
289
291
  // Grabber options - check if any non-default values are set
@@ -866,7 +868,11 @@ using namespace facebook::react;
866
868
  - (void)containerViewFooterDidChangeSize:(CGSize)newSize {
867
869
  [self syncFooterMetrics];
868
870
  [self setupSheetDetentsForSizeChange];
869
- [_controller setupAccessibilityContainer];
871
+ [_controller refreshAccessibilityContainer];
872
+ }
873
+
874
+ - (void)containerViewDidMountTransaction {
875
+ [_controller refreshAccessibilityContainerIfFooterChanged];
870
876
  }
871
877
 
872
878
  - (void)containerViewPeekDidChangeSize:(CGSize)newSize {
@@ -882,11 +888,12 @@ using namespace facebook::react;
882
888
 
883
889
  - (void)viewControllerWillPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
884
890
  _controller.activeDetentIndex = index;
891
+ // Before emitting, so an input focused in onWillPresent raises a tracked keyboard
892
+ [_containerView setupKeyboardObserverWithViewController:_controller];
885
893
  [TrueSheetLifecycleEvents emitWillPresent:_eventEmitter index:index position:position detent:detent];
886
894
  }
887
895
 
888
896
  - (void)viewControllerDidPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
889
- [_containerView setupKeyboardObserverWithViewController:_controller];
890
897
  [TrueSheetLifecycleEvents emitDidPresent:_eventEmitter index:index position:position detent:detent];
891
898
 
892
899
  if (_pendingPropsUpdate) {
@@ -84,6 +84,7 @@ NS_ASSUME_NONNULL_BEGIN
84
84
  @property (nonatomic, assign) facebook::react::TrueSheetViewBackgroundBlur backgroundBlur;
85
85
  @property (nonatomic, assign) facebook::react::TrueSheetViewPresentation presentation;
86
86
  @property (nonatomic, assign) facebook::react::TrueSheetViewPlacement placement;
87
+ @property (nonatomic, assign) facebook::react::TrueSheetViewFoldOptionsStruct foldOptions;
87
88
  @property (nonatomic, assign) facebook::react::TrueSheetViewInsetAdjustment insetAdjustment;
88
89
  @property (nonatomic, assign) BOOL scrollingExpandsSheet;
89
90
  @property (nonatomic, assign) CGFloat footerKeyboardOffset;
@@ -109,6 +110,13 @@ NS_ASSUME_NONNULL_BEGIN
109
110
  * announced — ahead of the grow/shrink animation, unlike keyboardSheetGrown.
110
111
  */
111
112
  @property (nonatomic, assign) CGFloat keyboardHeight;
113
+
114
+ /**
115
+ * How far UIKit grows the sheet for the iPadOS minimized keyboard, which it
116
+ * treats as docked. Taken off every detent so the sheet stays put.
117
+ */
118
+ @property (nonatomic, assign) CGFloat minimizedKeyboardOverlap;
119
+
112
120
  @property (nonatomic, readonly) BOOL isTopmostPresentedController;
113
121
  @property (nonatomic, readonly) BOOL isStackedBehindChild;
114
122
  @property (nonatomic, weak, nullable) UIView *accessibilityContentView;
@@ -130,6 +138,9 @@ NS_ASSUME_NONNULL_BEGIN
130
138
  @property (nonatomic, assign) CGFloat appliedFooterBottomInset;
131
139
 
132
140
  - (void)setupAccessibilityContainer;
141
+ - (void)refreshAccessibilityContainer;
142
+ - (void)refreshAccessibilityContainerIfFooterChanged;
143
+
133
144
  - (void)applyActiveDetent;
134
145
  - (void)setupActiveDetentWithIndex:(NSInteger)index;
135
146
  - (void)resizeToDetentIndex:(NSInteger)index;
@@ -138,6 +149,7 @@ NS_ASSUME_NONNULL_BEGIN
138
149
  - (void)setupSheetDetents;
139
150
  - (void)setupSheetDetentsForSizeChange;
140
151
  - (void)setupSheetDetentsForDetentsChange;
152
+ - (void)invalidateDetents;
141
153
  - (void)setupDraggable;
142
154
  - (void)setupAnchorViewInView:(UIView *)parentView;
143
155