react-native-screens 4.0.0-beta.1 → 4.0.0-beta.10

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 (107) hide show
  1. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +61 -0
  2. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +14 -0
  3. package/android/src/main/java/com/swmansion/rnscreens/InsetsObserverProxy.kt +2 -4
  4. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +46 -7
  5. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +24 -9
  6. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +37 -17
  7. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +1 -2
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigShadowNode.kt +25 -0
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +18 -0
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +6 -1
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +1 -0
  12. package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +17 -0
  13. package/android/src/main/java/com/swmansion/rnscreens/utils/PaddingBundle.kt +8 -0
  14. package/android/src/main/jni/rnscreens.h +2 -0
  15. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +39 -0
  16. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigComponentDescriptor.h +44 -0
  17. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.cpp +8 -0
  18. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigShadowNode.h +32 -0
  19. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.cpp +23 -0
  20. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderConfigState.h +50 -0
  21. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewComponentDescriptor.h +27 -0
  22. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.cpp +8 -0
  23. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewShadowNode.h +32 -0
  24. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.cpp +15 -0
  25. package/common/cpp/react/renderer/components/rnscreens/RNSScreenStackHeaderSubviewState.h +40 -0
  26. package/ios/RNSConvert.mm +0 -1
  27. package/ios/RNSScreen.h +9 -0
  28. package/ios/RNSScreen.mm +37 -8
  29. package/ios/RNSScreenStack.mm +79 -1
  30. package/ios/RNSScreenStackHeaderConfig.h +63 -0
  31. package/ios/RNSScreenStackHeaderConfig.mm +126 -9
  32. package/ios/RNSScreenStackHeaderSubview.mm +26 -0
  33. package/ios/utils/UINavigationBar+RNSUtility.h +37 -0
  34. package/ios/utils/UINavigationBar+RNSUtility.mm +44 -0
  35. package/ios/utils/UIView+RNSUtility.mm +0 -1
  36. package/lib/commonjs/components/Screen.js +58 -7
  37. package/lib/commonjs/components/Screen.js.map +1 -1
  38. package/lib/commonjs/components/ScreenContentWrapper.web.js +11 -0
  39. package/lib/commonjs/components/ScreenContentWrapper.web.js.map +1 -0
  40. package/lib/commonjs/components/ScreenFooter.web.js +11 -0
  41. package/lib/commonjs/components/ScreenFooter.web.js.map +1 -0
  42. package/lib/commonjs/components/ScreenStackHeaderConfig.js +53 -17
  43. package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
  44. package/lib/commonjs/components/helpers/usePrevious.js +15 -0
  45. package/lib/commonjs/components/helpers/usePrevious.js.map +1 -0
  46. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  47. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  48. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +3 -1
  49. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  50. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +3 -1
  51. package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  52. package/lib/commonjs/native-stack/views/NativeStackView.js +4 -10
  53. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  54. package/lib/module/components/Screen.js +58 -7
  55. package/lib/module/components/Screen.js.map +1 -1
  56. package/lib/module/components/ScreenContentWrapper.web.js +5 -0
  57. package/lib/module/components/ScreenContentWrapper.web.js.map +1 -0
  58. package/lib/module/components/ScreenFooter.web.js +5 -0
  59. package/lib/module/components/ScreenFooter.web.js.map +1 -0
  60. package/lib/module/components/ScreenStackHeaderConfig.js +50 -16
  61. package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
  62. package/lib/module/components/helpers/usePrevious.js +9 -0
  63. package/lib/module/components/helpers/usePrevious.js.map +1 -0
  64. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  65. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  66. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +3 -1
  67. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  68. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +3 -1
  69. package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  70. package/lib/module/native-stack/views/NativeStackView.js +4 -10
  71. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  72. package/lib/typescript/components/Screen.d.ts +5 -1
  73. package/lib/typescript/components/Screen.d.ts.map +1 -1
  74. package/lib/typescript/components/ScreenContentWrapper.web.d.ts +5 -0
  75. package/lib/typescript/components/ScreenContentWrapper.web.d.ts.map +1 -0
  76. package/lib/typescript/components/ScreenFooter.web.d.ts +5 -0
  77. package/lib/typescript/components/ScreenFooter.web.d.ts.map +1 -0
  78. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts +1 -1
  79. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
  80. package/lib/typescript/components/helpers/usePrevious.d.ts +2 -0
  81. package/lib/typescript/components/helpers/usePrevious.d.ts.map +1 -0
  82. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +1 -0
  83. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  84. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -1
  85. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  86. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  87. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  88. package/lib/typescript/native-stack/types.d.ts +2 -3
  89. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  90. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  91. package/lib/typescript/types.d.ts +26 -9
  92. package/lib/typescript/types.d.ts.map +1 -1
  93. package/native-stack/README.md +3 -2
  94. package/package.json +1 -1
  95. package/src/components/Screen.tsx +97 -12
  96. package/src/components/ScreenContentWrapper.web.tsx +6 -0
  97. package/src/components/ScreenFooter.web.tsx +6 -0
  98. package/src/components/ScreenStackHeaderConfig.tsx +59 -26
  99. package/src/components/helpers/usePrevious.tsx +11 -0
  100. package/src/fabric/ModalScreenNativeComponent.ts +1 -0
  101. package/src/fabric/ScreenNativeComponent.ts +0 -1
  102. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +3 -1
  103. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +3 -1
  104. package/src/native-stack/types.tsx +2 -3
  105. package/src/native-stack/views/NativeStackView.tsx +4 -10
  106. package/src/types.tsx +29 -13
  107. package/windows/RNScreens/Screen.h +0 -1
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <react/renderer/components/rnscreens/EventEmitters.h>
5
+ #include <react/renderer/components/rnscreens/Props.h>
6
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
7
+ #include <react/renderer/core/LayoutContext.h>
8
+ #include "FrameCorrectionModes.h"
9
+ #include "RNSScreenStackHeaderConfigState.h"
10
+
11
+ namespace facebook::react {
12
+
13
+ using namespace rnscreens;
14
+
15
+ JSI_EXPORT extern const char RNSScreenStackHeaderConfigComponentName[];
16
+
17
+ class JSI_EXPORT RNSScreenStackHeaderConfigShadowNode final
18
+ : public ConcreteViewShadowNode<
19
+ RNSScreenStackHeaderConfigComponentName,
20
+ RNSScreenStackHeaderConfigProps,
21
+ RNSScreenStackHeaderConfigEventEmitter,
22
+ RNSScreenStackHeaderConfigState> {
23
+ public:
24
+ using ConcreteViewShadowNode::ConcreteViewShadowNode;
25
+ using StateData = ConcreteViewShadowNode::ConcreteStateData;
26
+
27
+ #pragma mark - ShadowNode overrides
28
+
29
+ #pragma mark - Custom interface
30
+ };
31
+
32
+ } // namespace facebook::react
@@ -0,0 +1,23 @@
1
+ #include "RNSScreenStackHeaderConfigState.h"
2
+
3
+ namespace facebook {
4
+ namespace react {
5
+
6
+ #ifdef ANDROID
7
+ folly::dynamic RNSScreenStackHeaderConfigState::getDynamic() const {
8
+ return folly::dynamic::object("paddingStart", paddingStart_)(
9
+ "paddingEnd_", paddingEnd_);
10
+ }
11
+
12
+ #endif
13
+
14
+ Float RNSScreenStackHeaderConfigState::getPaddingStart() const noexcept {
15
+ return paddingStart_;
16
+ }
17
+
18
+ Float RNSScreenStackHeaderConfigState::getPaddingEnd() const noexcept {
19
+ return paddingEnd_;
20
+ }
21
+
22
+ } // namespace react
23
+ } // namespace facebook
@@ -0,0 +1,50 @@
1
+ #pragma once
2
+
3
+ #include <react/renderer/core/graphicsConversions.h>
4
+ #include <react/renderer/graphics/Float.h>
5
+
6
+ #ifdef ANDROID
7
+ #include <folly/dynamic.h>
8
+ #include <react/renderer/mapbuffer/MapBuffer.h>
9
+ #include <react/renderer/mapbuffer/MapBufferBuilder.h>
10
+ #endif
11
+
12
+ namespace facebook::react {
13
+
14
+ class JSI_EXPORT RNSScreenStackHeaderConfigState final {
15
+ public:
16
+ using Shared = std::shared_ptr<const RNSScreenStackHeaderConfigState>;
17
+
18
+ RNSScreenStackHeaderConfigState() = default;
19
+
20
+ RNSScreenStackHeaderConfigState(Float paddingStart, Float paddingEnd)
21
+ : paddingStart_{paddingStart}, paddingEnd_{paddingEnd} {}
22
+
23
+ #ifdef ANDROID
24
+ RNSScreenStackHeaderConfigState(
25
+ RNSScreenStackHeaderConfigState const &previousState,
26
+ folly::dynamic data)
27
+ : paddingStart_{static_cast<Float>(data["paddingStart"].getDouble())},
28
+ paddingEnd_{static_cast<Float>(data["paddingEnd"].getDouble())} {}
29
+ #endif
30
+
31
+ #ifdef ANDROID
32
+ folly::dynamic getDynamic() const;
33
+ MapBuffer getMapBuffer() const {
34
+ return MapBufferBuilder::EMPTY();
35
+ };
36
+
37
+ #endif
38
+
39
+ #pragma mark - Getters
40
+
41
+ [[nodiscard]] Float getPaddingStart() const noexcept;
42
+
43
+ [[nodiscard]] Float getPaddingEnd() const noexcept;
44
+
45
+ private:
46
+ Float paddingStart_{0.f};
47
+ Float paddingEnd_{0.f};
48
+ };
49
+
50
+ } // namespace facebook::react
@@ -0,0 +1,27 @@
1
+ #pragma once
2
+
3
+ #ifdef ANDROID
4
+ #include <fbjni/fbjni.h>
5
+ #endif
6
+ #include <react/debug/react_native_assert.h>
7
+ #include <react/renderer/components/rnscreens/Props.h>
8
+ #include <react/renderer/components/rnscreens/utils/RectUtil.h>
9
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
10
+ #include "RNSScreenStackHeaderSubviewShadowNode.h"
11
+
12
+ namespace facebook::react {
13
+
14
+ using namespace rnscreens;
15
+
16
+ class RNSScreenStackHeaderSubviewComponentDescriptor final
17
+ : public ConcreteComponentDescriptor<
18
+ RNSScreenStackHeaderSubviewShadowNode> {
19
+ public:
20
+ using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
21
+
22
+ void adopt(ShadowNode &shadowNode) const override {
23
+ ConcreteComponentDescriptor::adopt(shadowNode);
24
+ }
25
+ };
26
+
27
+ } // namespace facebook::react
@@ -0,0 +1,8 @@
1
+ #include "RNSScreenStackHeaderSubviewShadowNode.h"
2
+
3
+ namespace facebook::react {
4
+
5
+ extern const char RNSScreenStackHeaderSubviewComponentName[] =
6
+ "RNSScreenStackHeaderSubview";
7
+
8
+ }
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <react/renderer/components/rnscreens/EventEmitters.h>
5
+ #include <react/renderer/components/rnscreens/Props.h>
6
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
7
+ #include <react/renderer/core/LayoutContext.h>
8
+ #include "FrameCorrectionModes.h"
9
+ #include "RNSScreenStackHeaderSubviewState.h"
10
+
11
+ namespace facebook::react {
12
+
13
+ using namespace rnscreens;
14
+
15
+ JSI_EXPORT extern const char RNSScreenStackHeaderSubviewComponentName[];
16
+
17
+ class JSI_EXPORT RNSScreenStackHeaderSubviewShadowNode final
18
+ : public ConcreteViewShadowNode<
19
+ RNSScreenStackHeaderSubviewComponentName,
20
+ RNSScreenStackHeaderSubviewProps,
21
+ RNSScreenStackHeaderSubviewEventEmitter,
22
+ RNSScreenStackHeaderSubviewState> {
23
+ public:
24
+ using ConcreteViewShadowNode::ConcreteViewShadowNode;
25
+ using StateData = ConcreteViewShadowNode::ConcreteStateData;
26
+
27
+ #pragma mark - ShadowNode overrides
28
+
29
+ #pragma mark - Custom interface
30
+ };
31
+
32
+ } // namespace facebook::react
@@ -0,0 +1,15 @@
1
+ #include "RNSScreenStackHeaderSubviewState.h"
2
+
3
+ namespace facebook {
4
+ namespace react {
5
+
6
+ using namespace rnscreens;
7
+
8
+ #ifdef ANDROID
9
+ folly::dynamic RNSScreenStackHeaderSubviewState::getDynamic() const {
10
+ return folly::dynamic::object();
11
+ }
12
+ #endif
13
+
14
+ } // namespace react
15
+ } // namespace facebook
@@ -0,0 +1,40 @@
1
+ #pragma once
2
+
3
+ #include <react/renderer/core/graphicsConversions.h>
4
+ #include <react/renderer/graphics/Float.h>
5
+
6
+ #ifdef ANDROID
7
+ #include <folly/dynamic.h>
8
+ #include <react/renderer/mapbuffer/MapBuffer.h>
9
+ #include <react/renderer/mapbuffer/MapBufferBuilder.h>
10
+ #endif
11
+
12
+ #include "FrameCorrectionModes.h"
13
+
14
+ namespace facebook::react {
15
+
16
+ using namespace rnscreens;
17
+
18
+ class JSI_EXPORT RNSScreenStackHeaderSubviewState final {
19
+ public:
20
+ using Shared = std::shared_ptr<const RNSScreenStackHeaderSubviewState>;
21
+
22
+ RNSScreenStackHeaderSubviewState() = default;
23
+
24
+ #ifdef ANDROID
25
+ RNSScreenStackHeaderSubviewState(
26
+ RNSScreenStackHeaderSubviewState const &previousState,
27
+ folly::dynamic data) {}
28
+ #endif
29
+
30
+ #ifdef ANDROID
31
+ folly::dynamic getDynamic() const;
32
+ MapBuffer getMapBuffer() const {
33
+ return MapBufferBuilder::EMPTY();
34
+ };
35
+ #endif
36
+
37
+ #pragma mark - Getters
38
+ };
39
+
40
+ } // namespace facebook::react
package/ios/RNSConvert.mm CHANGED
@@ -53,7 +53,6 @@
53
53
  switch (stackAnimation) {
54
54
  // these four are intentionally grouped
55
55
  case react::RNSScreenStackAnimation::Slide_from_right:
56
- case react::RNSScreenStackAnimation::Ios:
57
56
  case react::RNSScreenStackAnimation::Ios_from_right:
58
57
  case react::RNSScreenStackAnimation::Default:
59
58
  return RNSScreenStackAnimationDefault;
package/ios/RNSScreen.h CHANGED
@@ -90,6 +90,7 @@ namespace react = facebook::react;
90
90
  @property (nonatomic) NSNumber *sheetLargestUndimmedDetent;
91
91
  @property (nonatomic) BOOL sheetGrabberVisible;
92
92
  @property (nonatomic) CGFloat sheetCornerRadius;
93
+ @property (nonatomic) NSInteger sheetInitialDetent;
93
94
  @property (nonatomic) BOOL sheetExpandsWhenScrolledToEdge;
94
95
  #endif // !TARGET_OS_TV
95
96
 
@@ -132,6 +133,14 @@ namespace react = facebook::react;
132
133
  - (BOOL)isModal;
133
134
  - (BOOL)isPresentedAsNativeModal;
134
135
 
136
+ /**
137
+ * Tell `Screen` component that it has been removed from react state and can safely cleanup
138
+ * any retained resources.
139
+ *
140
+ * Note, that on old architecture this method might be called by RN via `RCTInvalidating` protocol.
141
+ */
142
+ - (void)invalidate;
143
+
135
144
  /// Looks for header configuration in instance's `reactSubviews` and returns it. If not present returns `nil`.
136
145
  - (RNSScreenStackHeaderConfig *_Nullable)findHeaderConfig;
137
146
 
package/ios/RNSScreen.mm CHANGED
@@ -304,6 +304,10 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
304
304
  {
305
305
  int activityState = [activityStateOrNil intValue];
306
306
  if (activityStateOrNil != nil && activityState != -1 && activityState != _activityState) {
307
+ if ([_controller.navigationController isKindOfClass:RNSNavigationController.class] &&
308
+ _activityState < activityState) {
309
+ RCTLogError(@"[RNScreens] activityState can only progress in NativeStack");
310
+ }
307
311
  _activityState = activityState;
308
312
  [_reactSuperview markChildUpdated];
309
313
  }
@@ -745,6 +749,12 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
745
749
  self.controller.modalPresentationStyle == UIModalPresentationOverCurrentContext;
746
750
  }
747
751
 
752
+ - (void)invalidate
753
+ {
754
+ _controller = nil;
755
+ [_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
756
+ }
757
+
748
758
  #if !TARGET_OS_TV && !TARGET_OS_VISION
749
759
 
750
760
  - (void)setPropertyForSheet:(UISheetPresentationController *)sheet
@@ -889,8 +899,8 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
889
899
  sheet.delegate = self;
890
900
  #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \
891
901
  __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
892
- if (_sheetAllowedDetents.count > 0) {
893
- if (@available(iOS 16.0, *)) {
902
+ if (@available(iOS 16.0, *)) {
903
+ if (_sheetAllowedDetents.count > 0) {
894
904
  if (_sheetAllowedDetents.count == 1 && [_sheetAllowedDetents[0] integerValue] == SHEET_FIT_TO_CONTENTS) {
895
905
  // This is `fitToContents` case, where sheet should be just high to display its contents.
896
906
  // Paper: we do not set anything here, we will set once React computed layout of our React's children, namely
@@ -944,6 +954,26 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
944
954
  }
945
955
  }
946
956
 
957
+ if (_sheetInitialDetent > 0 && _sheetInitialDetent < _sheetAllowedDetents.count) {
958
+ #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \
959
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0
960
+ if (@available(iOS 16.0, *)) {
961
+ UISheetPresentationControllerDetent *detent = sheet.detents[_sheetInitialDetent];
962
+ [self setSelectedDetentForSheet:sheet to:detent.identifier animate:YES];
963
+ } else
964
+ #endif // Check for iOS >= 16
965
+ {
966
+ if (_sheetInitialDetent < 2) {
967
+ [self setSelectedDetentForSheet:sheet to:UISheetPresentationControllerDetentIdentifierLarge animate:YES];
968
+ } else {
969
+ RCTLogError(
970
+ @"[RNScreens] sheetInitialDetent out of bounds, on iOS versions below 16 sheetAllowedDetents is ignored in favor of an array of two system-defined detents");
971
+ }
972
+ }
973
+ } else if (_sheetInitialDetent != 0) {
974
+ RCTLogError(@"[RNScreens] sheetInitialDetent out of bounds for sheetAllowedDetents array");
975
+ }
976
+
947
977
  sheet.prefersScrollingExpandsWhenScrolledToEdge = _sheetExpandsWhenScrolledToEdge;
948
978
  [self setGrabberVisibleForSheet:sheet to:_sheetGrabberVisible animate:YES];
949
979
  [self setCornerRadiusForSheet:sheet to:_sheetCornerRadius animate:YES];
@@ -1151,6 +1181,10 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
1151
1181
  [self setSheetAllowedDetents:[RNSConvert detentFractionsArrayFromVector:newScreenProps.sheetAllowedDetents]];
1152
1182
  }
1153
1183
 
1184
+ if (newScreenProps.sheetInitialDetent != oldScreenProps.sheetInitialDetent) {
1185
+ [self setSheetInitialDetent:newScreenProps.sheetInitialDetent];
1186
+ }
1187
+
1154
1188
  if (newScreenProps.sheetLargestUndimmedDetent != oldScreenProps.sheetLargestUndimmedDetent) {
1155
1189
  [self setSheetLargestUndimmedDetent:[NSNumber numberWithInt:newScreenProps.sheetLargestUndimmedDetent]];
1156
1190
  }
@@ -1237,11 +1271,6 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
1237
1271
  // subviews
1238
1272
  }
1239
1273
 
1240
- - (void)invalidate
1241
- {
1242
- _controller = nil;
1243
- [_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
1244
- }
1245
1274
  #endif
1246
1275
 
1247
1276
  @end
@@ -1864,6 +1893,7 @@ RCT_EXPORT_VIEW_PROPERTY(sheetAllowedDetents, NSArray<NSNumber *> *);
1864
1893
  RCT_EXPORT_VIEW_PROPERTY(sheetLargestUndimmedDetent, NSNumber *);
1865
1894
  RCT_EXPORT_VIEW_PROPERTY(sheetGrabberVisible, BOOL);
1866
1895
  RCT_EXPORT_VIEW_PROPERTY(sheetCornerRadius, CGFloat);
1896
+ RCT_EXPORT_VIEW_PROPERTY(sheetInitialDetent, NSInteger);
1867
1897
  RCT_EXPORT_VIEW_PROPERTY(sheetExpandsWhenScrolledToEdge, BOOL);
1868
1898
  #endif
1869
1899
 
@@ -1936,7 +1966,6 @@ RCT_ENUM_CONVERTER(
1936
1966
  @"slide_from_bottom" : @(RNSScreenStackAnimationSlideFromBottom),
1937
1967
  @"slide_from_right" : @(RNSScreenStackAnimationDefault),
1938
1968
  @"slide_from_left" : @(RNSScreenStackAnimationSlideFromLeft),
1939
- @"ios" : @(RNSScreenStackAnimationDefault),
1940
1969
  @"ios_from_right" : @(RNSScreenStackAnimationDefault),
1941
1970
  @"ios_from_left" : @(RNSScreenStackAnimationSlideFromLeft),
1942
1971
  }),
@@ -25,6 +25,7 @@
25
25
  #import "RNSScreenStackAnimator.h"
26
26
  #import "RNSScreenStackHeaderConfig.h"
27
27
  #import "RNSScreenWindowTraits.h"
28
+ #import "utils/UINavigationBar+RNSUtility.h"
28
29
 
29
30
  #import "UIView+RNSUtility.h"
30
31
 
@@ -82,6 +83,8 @@ namespace react = facebook::react;
82
83
  if (![screenController hasNestedStack] && isNotDismissingModal) {
83
84
  [screenController calculateAndNotifyHeaderHeightChangeIsModal:NO];
84
85
  }
86
+
87
+ [self maybeUpdateHeaderInsetsInShadowTreeForScreen:screenController];
85
88
  }
86
89
  }
87
90
 
@@ -94,6 +97,35 @@ namespace react = facebook::react;
94
97
  {
95
98
  return [self topViewController];
96
99
  }
100
+
101
+ - (void)maybeUpdateHeaderInsetsInShadowTreeForScreen:(RNSScreen *)screenController
102
+ {
103
+ // This might happen e.g. if there is only native title present in navigation bar.
104
+ if (self.navigationBar.subviews.count < 2) {
105
+ return;
106
+ }
107
+
108
+ auto headerConfig = screenController.screenView.findHeaderConfig;
109
+ if (headerConfig == nil || !headerConfig.shouldHeaderBeVisible) {
110
+ return;
111
+ }
112
+
113
+ NSDirectionalEdgeInsets navBarMargins = [self.navigationBar directionalLayoutMargins];
114
+ NSDirectionalEdgeInsets navBarContentMargins =
115
+ [self.navigationBar.rnscreens_findContentView directionalLayoutMargins];
116
+
117
+ BOOL isDisplayingBackButton = [headerConfig shouldBackButtonBeVisibleInNavigationBar:self.navigationBar];
118
+
119
+ // 44.0 is just "closed eyes default". It is so on device I've tested with, nothing more.
120
+ UIView *barButtonView = isDisplayingBackButton ? self.navigationBar.rnscreens_findBackButtonWrapperView : nil;
121
+ CGFloat platformBackButtonWidth = barButtonView != nil ? barButtonView.frame.size.width : 44.0f;
122
+
123
+ [headerConfig updateHeaderInsetsInShadowTreeTo:NSDirectionalEdgeInsets{
124
+ .leading = navBarMargins.leading + navBarContentMargins.leading +
125
+ (isDisplayingBackButton ? platformBackButtonWidth : 0),
126
+ .trailing = navBarMargins.trailing + navBarContentMargins.trailing,
127
+ }];
128
+ }
97
129
  #endif
98
130
 
99
131
  @end
@@ -120,6 +152,13 @@ namespace react = facebook::react;
120
152
  UIPercentDrivenInteractiveTransition *_interactionController;
121
153
  __weak RNSScreenStackManager *_manager;
122
154
  BOOL _updateScheduled;
155
+ #ifdef RCT_NEW_ARCH_ENABLED
156
+ /// Screens that are subject of `ShadowViewMutation::Type::Delete` mutation
157
+ /// in current transaction. This vector should be populated when we receive notification via
158
+ /// `RCTMountingObserving` protocol, that a transaction will be performed, and should
159
+ /// be cleaned up when we're notified that the transaction has been completed.
160
+ std::vector<__strong RNSScreenView *> _toBeDeletedScreens;
161
+ #endif // RCT_NEW_ARCH_ENABLED
123
162
  }
124
163
 
125
164
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -641,7 +680,7 @@ namespace react = facebook::react;
641
680
  NSMutableArray<UIViewController *> *pushControllers = [NSMutableArray new];
642
681
  NSMutableArray<UIViewController *> *modalControllers = [NSMutableArray new];
643
682
  for (RNSScreenView *screen in _reactSubviews) {
644
- if (!screen.dismissed && screen.controller != nil) {
683
+ if (!screen.dismissed && screen.controller != nil && screen.activityState != RNSActivityStateInactive) {
645
684
  if (pushControllers.count == 0) {
646
685
  // first screen on the list needs to be places as "push controller"
647
686
  [pushControllers addObject:screen.controller];
@@ -915,6 +954,7 @@ namespace react = facebook::react;
915
954
  - (void)markChildUpdated
916
955
  {
917
956
  // do nothing
957
+ [self updateContainer];
918
958
  }
919
959
 
920
960
  - (void)didUpdateChildren
@@ -1118,6 +1158,16 @@ namespace react = facebook::react;
1118
1158
  // `- [RNSScreenStackView mountingTransactionDidMount: withSurfaceTelemetry:]`
1119
1159
  }
1120
1160
 
1161
+ - (nullable RNSScreenView *)childScreenForTag:(react::Tag)tag
1162
+ {
1163
+ for (RNSScreenView *child in _reactSubviews) {
1164
+ if (child.tag == tag) {
1165
+ return child;
1166
+ }
1167
+ }
1168
+ return nil;
1169
+ }
1170
+
1121
1171
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
1122
1172
  {
1123
1173
  RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView;
@@ -1151,6 +1201,19 @@ namespace react = facebook::react;
1151
1201
  [screenChildComponent removeFromSuperview];
1152
1202
  }
1153
1203
 
1204
+ - (void)mountingTransactionWillMount:(const facebook::react::MountingTransaction &)transaction
1205
+ withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1206
+ {
1207
+ for (const auto &mutation : transaction.getMutations()) {
1208
+ if (mutation.type == react::ShadowViewMutation::Delete) {
1209
+ RNSScreenView *_Nullable toBeRemovedChild = [self childScreenForTag:mutation.oldChildShadowView.tag];
1210
+ if (toBeRemovedChild != nil) {
1211
+ _toBeDeletedScreens.push_back(toBeRemovedChild);
1212
+ }
1213
+ }
1214
+ }
1215
+ }
1216
+
1154
1217
  - (void)mountingTransactionDidMount:(const facebook::react::MountingTransaction &)transaction
1155
1218
  withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1156
1219
  {
@@ -1167,6 +1230,21 @@ namespace react = facebook::react;
1167
1230
  break;
1168
1231
  }
1169
1232
  }
1233
+
1234
+ if (!self->_toBeDeletedScreens.empty()) {
1235
+ __weak RNSScreenStackView *weakSelf = self;
1236
+ // We want to run after container updates are performed (transitions etc.)
1237
+ dispatch_async(dispatch_get_main_queue(), ^{
1238
+ RNSScreenStackView *_Nullable strongSelf = weakSelf;
1239
+ if (strongSelf == nil) {
1240
+ return;
1241
+ }
1242
+ for (RNSScreenView *screenRef : strongSelf->_toBeDeletedScreens) {
1243
+ [screenRef invalidate];
1244
+ }
1245
+ strongSelf->_toBeDeletedScreens.clear();
1246
+ });
1247
+ }
1170
1248
  }
1171
1249
 
1172
1250
  - (void)prepareForRecycle
@@ -1,6 +1,7 @@
1
1
  #ifdef RCT_NEW_ARCH_ENABLED
2
2
  #import <React/RCTViewComponentView.h>
3
3
  #else
4
+ #import <React/RCTShadowView.h>
4
5
  #import <React/RCTViewManager.h>
5
6
  #endif
6
7
 
@@ -61,12 +62,74 @@
61
62
  animated:(BOOL)animated
62
63
  withConfig:(RNSScreenStackHeaderConfig *)config;
63
64
 
65
+ /**
66
+ * Allows to send information with insets to the corresponding node in shadow tree.
67
+ * Currently only horizontal insets are send through. Vertical ones are filtered out.
68
+ */
69
+ - (void)updateHeaderInsetsInShadowTreeTo:(NSDirectionalEdgeInsets)insets;
70
+
71
+ /**
72
+ * Returns true iff subview of given `type` is present.
73
+ *
74
+ * **Please note that the subviews are not mounted under the header config in HostTree**
75
+ * This method should serve only to check whether given subview type has been rendered.
76
+ */
77
+ - (BOOL)hasSubviewOfType:(RNSScreenStackHeaderSubviewType)type;
78
+
79
+ /**
80
+ * Returns `true` iff subview of type `left` is present.
81
+ *
82
+ * **Please note that the subviews are not mounted under the header config in HostTree**
83
+ * This method should serve only to check whether given subview type has been rendered.
84
+ */
85
+ - (BOOL)hasSubviewLeft;
86
+
87
+ /**
88
+ * Returns
89
+ * - `YES` on Paper, when `self.hide == NO`
90
+ * - `YES` on Fabric, when `self.show == YES`
91
+ * - `NO` otherwise.
92
+ *
93
+ * Convenience method, so that we do not need ifdefs in every callsite.
94
+ */
95
+ - (BOOL)shouldHeaderBeVisible;
96
+
97
+ /**
98
+ * @returns`true` iff the applying this header config instance to a view controller will
99
+ * result in visible back button if feasible.
100
+ */
101
+ - (BOOL)shouldBackButtonBeVisibleInNavigationBar:(nullable UINavigationBar *)navBar;
102
+
64
103
  @end
65
104
 
66
105
  @interface RNSScreenStackHeaderConfigManager : RCTViewManager
67
106
 
68
107
  @end
69
108
 
109
+ #ifdef RCT_NEW_ARCH_ENABLED
110
+ #else
111
+
112
+ /**
113
+ * Used as local data send to shadow view on Paper. This helps us to provide Yoga
114
+ * with knowledge of native insets in the navigation bar.
115
+ */
116
+ @interface RNSHeaderConfigInsetsPayload : NSObject
117
+
118
+ @property (nonatomic) NSDirectionalEdgeInsets insets;
119
+
120
+ - (instancetype)initWithInsets:(NSDirectionalEdgeInsets)insets NS_DESIGNATED_INITIALIZER;
121
+
122
+ @end
123
+
124
+ /**
125
+ * Custom shadow view for header config. This is used on Paper to provide Yoga
126
+ * with knowledge of native header insets (horizontal padding).
127
+ */
128
+ @interface RNSScreenStackHeaderConfigShadowView : RCTShadowView
129
+
130
+ @end
131
+ #endif
132
+
70
133
  @interface RCTConvert (RNSScreenStackHeader)
71
134
 
72
135
  + (UIBlurEffectStyle)UIBlurEffectStyle:(id)json;