react-native-screens 5.0.0-alpha.2 → 5.0.0-alpha.4

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 (456) hide show
  1. package/Package.swift +87 -0
  2. package/README.md +0 -11
  3. package/android/build.gradle +1 -0
  4. package/android/consumer-rules.pro +3 -0
  5. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderConfigViewGroup.kt +2 -0
  6. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderSubviewViewGroup.kt +2 -0
  7. package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledViewGroup.kt +18 -3
  8. package/android/src/main/cpp/NativeProxy.cpp +30 -6
  9. package/android/src/main/cpp/NativeProxy.h +7 -1
  10. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -2
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +7 -3
  12. package/android/src/main/java/com/swmansion/rnscreens/common/colorscheme/ColorSchemeCoordinator.kt +11 -1
  13. package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +17 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/common/container/ContainerItem.kt +13 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/common/text/ReactTextAppearance.kt +62 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearance.kt +20 -0
  17. package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearanceDefaults.kt +65 -0
  18. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetAppearanceCoordinator.kt +2 -2
  19. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetBehaviorController.kt +51 -20
  20. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/coordinator/FormSheetDimensionsCoordinator.kt +159 -0
  21. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/coordinator/FormSheetKeyboardCoordinator.kt +101 -0
  22. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetNativeDismissCoordinator.kt +2 -8
  23. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/dialog/FormSheetAvailableHeightProvider.kt +44 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetContainer.kt +1 -1
  25. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetDialog.kt +36 -4
  26. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/dialog/FormSheetDialogManager.kt +107 -0
  27. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeDelegate.kt +1 -1
  28. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeProvider.kt +1 -1
  29. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetDialogEventEmitter.kt +3 -1
  30. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/model/FormSheetConfig.kt +1 -1
  31. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/model/FormSheetDetents.kt +152 -0
  32. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetAnimatorFactory.kt +9 -10
  33. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetDimmingManager.kt +103 -0
  34. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetDismissalOrigin.kt +22 -0
  35. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetPresentation.kt +173 -0
  36. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetPresentationManager.kt +290 -0
  37. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentationState.kt +2 -2
  38. package/android/src/main/java/com/swmansion/rnscreens/core/modals/formsheet/presentation/FormSheetStackRegistry.kt +28 -0
  39. package/android/src/main/java/com/swmansion/rnscreens/ext/FragmentManagerExt.kt +6 -0
  40. package/android/src/main/java/com/swmansion/rnscreens/helpers/FragmentManagerHelper.kt +0 -3
  41. package/android/src/main/java/com/swmansion/rnscreens/helpers/NoTintDrawable.kt +31 -0
  42. package/android/src/main/java/com/swmansion/rnscreens/helpers/PropIconResolver.kt +17 -23
  43. package/android/src/main/java/com/swmansion/rnscreens/helpers/ViewFinder.kt +0 -17
  44. package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +32 -3
  45. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenContainer.kt +35 -3
  46. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +15 -0
  47. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderConfig.kt +7 -1
  48. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderSubviewManager.kt +7 -0
  49. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackViewManager.kt +6 -0
  50. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/DimmingView.kt +2 -0
  51. package/android/src/main/java/com/swmansion/rnscreens/legacy/stack/views/ScreensCoordinatorLayout.kt +2 -0
  52. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapper.kt +3 -3
  53. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapperViewManager.kt +1 -1
  54. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDetentChangedEvent.kt +1 -1
  55. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidAppearEvent.kt +1 -1
  56. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidDisappearEvent.kt +1 -1
  57. package/android/src/main/java/com/swmansion/rnscreens/react/modals/formsheet/event/FormSheetDismissEvent.kt +29 -0
  58. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissEvent.kt +1 -1
  59. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissPreventedEvent.kt +1 -1
  60. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetSyncFlushEvent.kt +1 -1
  61. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillAppearEvent.kt +1 -1
  62. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillDisappearEvent.kt +1 -1
  63. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetContentView.kt +3 -3
  64. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHost.kt +5 -3
  65. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostEventEmitter.kt +17 -10
  66. package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostViewManager.kt +11 -9
  67. package/android/src/main/java/com/swmansion/rnscreens/safearea/OnInterfaceInsetsChangeListener.kt +15 -0
  68. package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaProvider.kt +8 -8
  69. package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaView.kt +3 -2
  70. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +360 -101
  71. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderBackPressHandler.kt +11 -0
  72. package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +211 -113
  73. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +156 -24
  74. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderContentScrimDrawable.kt +36 -0
  75. package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderToolbar.kt +74 -0
  76. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderCollapsedTitleGravityMode.kt +6 -0
  77. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +162 -228
  78. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +385 -12
  79. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +5 -6
  80. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +29 -6
  81. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderDelegate.kt +0 -7
  82. package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +8 -7
  83. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +27 -280
  84. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuController.kt +448 -0
  85. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuDelegate.kt +10 -0
  86. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +28 -20
  87. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuConfig.kt +3 -55
  88. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuGroupMetadata.kt +1 -10
  89. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuItemConfig.kt +1 -3
  90. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuModel.kt +180 -0
  91. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementOptions.kt +57 -6
  92. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +3 -1
  93. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +1 -0
  94. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +4 -3
  95. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueue.kt +23 -9
  96. package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperation.kt +1 -0
  97. package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperationExecutor.kt +2 -1
  98. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +159 -21
  99. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerDelegate.kt +7 -0
  100. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerUpdateCoordinator.kt +5 -3
  101. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +27 -5
  102. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHostViewManager.kt +14 -0
  103. package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackUpdateBatchStateProviding.kt +10 -0
  104. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/PreventNativeDismissCallback.kt +2 -2
  105. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +4 -0
  106. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +50 -10
  107. package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragmentDelegate.kt +12 -0
  108. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceApplicator.kt +106 -10
  109. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +46 -7
  110. package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceModel.kt +3 -0
  111. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/CustomBottomNavigationView.kt +21 -1
  112. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/MenuHelpers.kt +5 -23
  113. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +72 -36
  114. package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainerDelegate.kt +11 -0
  115. package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +22 -2
  116. package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHostA11yCoordinator.kt +23 -2
  117. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +58 -17
  118. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenDelegate.kt +6 -0
  119. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenFragment.kt +3 -0
  120. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIcon.kt +82 -0
  121. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIconTinting.kt +17 -0
  122. package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenViewManager.kt +26 -19
  123. package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +20 -6
  124. package/android/src/main/java/com/swmansion/rnscreens/utils/RNSLog.kt +22 -6
  125. package/android/src/main/java/com/swmansion/rnscreens/utils/StyleUtils.kt +22 -0
  126. package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_available_space.xml +8 -0
  127. package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_entire_space.xml +8 -0
  128. package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_available_space.xml +8 -0
  129. package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_entire_space.xml +8 -0
  130. package/cpp/legacy/RNSScreenRemovalListener.cpp +31 -1
  131. package/cpp/legacy/RNSScreenRemovalListener.h +18 -3
  132. package/ios/RNSEnums.h +16 -1
  133. package/ios/conversion/RNSConversions.h +7 -108
  134. package/ios/helpers/image/RNSImageLoadingHelper.h +7 -0
  135. package/ios/helpers/image/RNSImageLoadingHelper.mm +9 -0
  136. package/ios/legacy/RNSBarButtonItem.mm +15 -0
  137. package/ios/legacy/RNSConvert.h +6 -0
  138. package/ios/legacy/RNSConvert.mm +17 -0
  139. package/ios/legacy/RNSFullWindowOverlay.mm +1 -1
  140. package/ios/legacy/RNSModalScreen.mm +1 -1
  141. package/ios/legacy/RNSNavigationBar.h +31 -0
  142. package/ios/legacy/RNSNavigationBar.mm +15 -0
  143. package/ios/legacy/RNSScreen.mm +130 -31
  144. package/ios/legacy/RNSScreenContentWrapper.mm +4 -1
  145. package/ios/legacy/RNSScreenStack.mm +202 -15
  146. package/ios/legacy/RNSScreenStackHeaderConfig.h +30 -0
  147. package/ios/legacy/RNSScreenStackHeaderConfig.mm +72 -17
  148. package/ios/legacy/RNSScreenStackHeaderSubview.mm +34 -1
  149. package/ios/legacy/RNSScreenWindowTraits.mm +5 -13
  150. package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.h +1 -3
  151. package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm +11 -22
  152. package/ios/modals/form-sheet/RNSFormSheetContentController.h +1 -1
  153. package/ios/modals/form-sheet/RNSFormSheetContentController.mm +7 -18
  154. package/ios/modals/form-sheet/RNSFormSheetHostComponentView.mm +4 -4
  155. package/ios/modals/form-sheet/RNSFormSheetHostShadowStateProxy.mm +2 -2
  156. package/ios/modals/form-sheet/RNSFormSheetUpdateFlags.h +3 -0
  157. package/ios/safe-area/RNSSafeAreaViewComponentView.mm +3 -14
  158. package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.mm +2 -3
  159. package/ios/split/RNSSplitAppearanceApplicator.h +4 -4
  160. package/ios/split/RNSSplitAppearanceApplicator.mm +53 -56
  161. package/ios/split/RNSSplitHostComponentEventEmitter.h +1 -0
  162. package/ios/split/RNSSplitHostComponentEventEmitter.mm +1 -1
  163. package/ios/split/RNSSplitHostComponentView.h +5 -15
  164. package/ios/split/RNSSplitHostComponentView.mm +55 -6
  165. package/ios/split/RNSSplitHostController.h +25 -6
  166. package/ios/split/RNSSplitHostController.mm +24 -92
  167. package/ios/split/RNSSplitHostProviders.h +67 -0
  168. package/ios/split/RNSSplitScreenComponentView.h +0 -39
  169. package/ios/split/RNSSplitScreenComponentView.mm +27 -10
  170. package/ios/split/RNSSplitScreenController.h +26 -3
  171. package/ios/split/RNSSplitScreenController.mm +13 -30
  172. package/ios/split/RNSSplitScreenShadowStateProxy.h +1 -40
  173. package/ios/split/RNSSplitScreenShadowStateProxy.mm +1 -26
  174. package/ios/split/conversion/RNSConversions-SplitView.h +56 -0
  175. package/ios/{conversion → split/conversion}/RNSConversions-SplitView.mm +4 -1
  176. package/ios/stack/conversion/RNSConversions-Stack.h +62 -0
  177. package/ios/stack/conversion/RNSConversions-Stack.mm +134 -0
  178. package/ios/stack/header/RNSHeaderItemVisibilityPriority.h +9 -0
  179. package/ios/stack/header/RNSStackHeaderAppearanceMapper.h +26 -0
  180. package/ios/stack/header/RNSStackHeaderAppearanceMapper.mm +88 -0
  181. package/ios/stack/header/RNSStackHeaderConfigComponentView.h +14 -1
  182. package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +103 -37
  183. package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +11 -0
  184. package/ios/stack/header/RNSStackHeaderConfigShadowStateProxy.mm +1 -1
  185. package/ios/stack/header/RNSStackHeaderContentFactory.mm +3 -0
  186. package/ios/stack/header/RNSStackHeaderIconResolver.mm +7 -0
  187. package/ios/stack/header/RNSStackHeaderItemComponentView.h +12 -3
  188. package/ios/stack/header/RNSStackHeaderItemComponentView.mm +72 -5
  189. package/ios/stack/header/RNSStackHeaderItemDataProviding.h +7 -0
  190. package/ios/stack/header/RNSStackHeaderItemShadowStateProxy.mm +1 -1
  191. package/ios/stack/header/RNSStackHeaderItemSpacerComponentView.mm +2 -1
  192. package/ios/stack/header/RNSStackHeaderMenuCoordinator.h +13 -0
  193. package/ios/stack/header/RNSStackHeaderMenuCoordinator.mm +24 -0
  194. package/ios/stack/header/RNSStackHeaderMenuFinder.h +8 -1
  195. package/ios/stack/header/RNSStackHeaderMenuFinder.mm +26 -9
  196. package/ios/stack/header/RNSStackHeaderMenuMapper.mm +4 -0
  197. package/ios/stack/host/RNSStackNavigationBar.h +25 -0
  198. package/ios/stack/host/RNSStackNavigationBar.mm +80 -0
  199. package/ios/stack/host/RNSStackNavigationBarCoordinator.h +8 -0
  200. package/ios/stack/host/RNSStackNavigationBarCoordinator.mm +11 -0
  201. package/ios/stack/host/RNSStackNavigationController.mm +13 -5
  202. package/ios/stack/host/RNSStackOperation.h +0 -2
  203. package/ios/stack/screen/RNSStackScreenComponentView.h +2 -1
  204. package/ios/stack/screen/RNSStackScreenComponentView.mm +32 -2
  205. package/ios/stack/screen/RNSStackScreenController.mm +12 -0
  206. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +8 -0
  207. package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +179 -24
  208. package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +110 -16
  209. package/ios/tabs/RNSTabBarItemCoordinator.h +16 -0
  210. package/ios/tabs/RNSTabBarItemCoordinator.mm +143 -0
  211. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.h +1 -1
  212. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +1 -1
  213. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +1 -1
  214. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryEventEmitter.mm +1 -1
  215. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryShadowStateProxy.mm +1 -1
  216. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.h +24 -0
  217. package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.mm +22 -0
  218. package/ios/tabs/conversion/RNSConversions-Tabs.h +100 -0
  219. package/ios/{conversion → tabs/conversion}/RNSConversions-Tabs.mm +105 -74
  220. package/ios/tabs/extensions/RNSTabsHostComponentView+RNSImageLoader.h +1 -1
  221. package/ios/tabs/host/RNSTabBarController.h +16 -0
  222. package/ios/tabs/host/RNSTabBarController.mm +516 -107
  223. package/ios/tabs/host/RNSTabsHostComponentView.h +4 -0
  224. package/ios/tabs/host/RNSTabsHostComponentView.mm +41 -4
  225. package/ios/tabs/host/RNSTabsHostEventEmitter.mm +1 -1
  226. package/ios/tabs/screen/RNSTabsScreenComponentView.h +21 -0
  227. package/ios/tabs/screen/RNSTabsScreenComponentView.mm +56 -56
  228. package/ios/tabs/screen/RNSTabsScreenViewController.mm +1 -0
  229. package/ios/utils/RNSDefines.h +15 -7
  230. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +37 -21
  231. package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  232. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +41 -4
  233. package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  234. package/lib/commonjs/components/stack/header/StackHeaderConfig.js +17 -0
  235. package/lib/commonjs/components/stack/header/StackHeaderConfig.js.map +1 -0
  236. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
  237. package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  238. package/lib/commonjs/components/stack/host/StackHost.js +17 -7
  239. package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
  240. package/lib/commonjs/components/stack/host/StackHost.web.js +0 -2
  241. package/lib/commonjs/components/stack/host/StackHost.web.js.map +1 -1
  242. package/lib/commonjs/components/stack/index.js.map +1 -1
  243. package/lib/commonjs/components/tabs/host/TabsHost.ios.js +3 -0
  244. package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
  245. package/lib/commonjs/components/tabs/host/{TabsHost.web.js → TabsHost.js} +1 -1
  246. package/lib/commonjs/components/tabs/host/TabsHost.js.map +1 -0
  247. package/lib/commonjs/components/tabs/index.js.map +1 -1
  248. package/lib/commonjs/components/tabs/screen/TabsScreen.android.js +3 -1
  249. package/lib/commonjs/components/tabs/screen/TabsScreen.android.js.map +1 -1
  250. package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js +10 -1
  251. package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js.map +1 -1
  252. package/lib/commonjs/components/tabs/screen/{TabsScreen.web.js → TabsScreen.js} +1 -1
  253. package/lib/commonjs/components/tabs/screen/TabsScreen.js.map +1 -0
  254. package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js → tabs/screen/TabsScreenIcon.types.js} +1 -1
  255. package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
  256. package/lib/commonjs/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  257. package/lib/commonjs/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  258. package/lib/commonjs/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  259. package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  260. package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  261. package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
  262. package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  263. package/lib/commonjs/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  264. package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
  265. package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  266. package/lib/commonjs/legacy/components/ScreenStackItem.js +31 -11
  267. package/lib/commonjs/legacy/components/ScreenStackItem.js.map +1 -1
  268. package/lib/module/components/stack/header/StackHeaderConfig.android.js +39 -23
  269. package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
  270. package/lib/module/components/stack/header/StackHeaderConfig.ios.js +43 -6
  271. package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
  272. package/lib/module/components/stack/header/StackHeaderConfig.js +10 -0
  273. package/lib/module/components/stack/header/StackHeaderConfig.js.map +1 -0
  274. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
  275. package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
  276. package/lib/module/components/stack/host/StackHost.js +18 -8
  277. package/lib/module/components/stack/host/StackHost.js.map +1 -1
  278. package/lib/module/components/stack/host/StackHost.web.js +0 -3
  279. package/lib/module/components/stack/host/StackHost.web.js.map +1 -1
  280. package/lib/module/components/stack/index.js.map +1 -1
  281. package/lib/module/components/tabs/host/TabsHost.ios.js +3 -0
  282. package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
  283. package/{src/components/tabs/host/TabsHost.web.tsx → lib/module/components/tabs/host/TabsHost.js} +1 -2
  284. package/lib/module/components/tabs/host/TabsHost.js.map +1 -0
  285. package/lib/module/components/tabs/index.js.map +1 -1
  286. package/lib/module/components/tabs/screen/TabsScreen.android.js +3 -1
  287. package/lib/module/components/tabs/screen/TabsScreen.android.js.map +1 -1
  288. package/lib/module/components/tabs/screen/TabsScreen.ios.js +10 -1
  289. package/lib/module/components/tabs/screen/TabsScreen.ios.js.map +1 -1
  290. package/{src/components/tabs/screen/TabsScreen.web.tsx → lib/module/components/tabs/screen/TabsScreen.js} +1 -2
  291. package/lib/module/components/tabs/screen/TabsScreen.js.map +1 -0
  292. package/lib/module/components/tabs/screen/TabsScreenIcon.types.js +2 -0
  293. package/lib/module/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
  294. package/lib/module/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
  295. package/lib/module/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
  296. package/lib/module/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
  297. package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
  298. package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
  299. package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
  300. package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
  301. package/lib/module/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
  302. package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
  303. package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
  304. package/lib/module/legacy/components/ScreenStackItem.js +31 -11
  305. package/lib/module/legacy/components/ScreenStackItem.js.map +1 -1
  306. package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +1 -1
  307. package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts +6 -3
  308. package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
  309. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +620 -24
  310. package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
  311. package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts +8 -0
  312. package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts.map +1 -0
  313. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts +6 -3
  314. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
  315. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +361 -2
  316. package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
  317. package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +4 -2
  318. package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts.map +1 -1
  319. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.d.ts.map +1 -1
  320. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +7 -0
  321. package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
  322. package/lib/typescript/components/stack/host/StackHost.d.ts +1 -1
  323. package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
  324. package/lib/typescript/components/stack/host/StackHost.types.d.ts +47 -0
  325. package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
  326. package/lib/typescript/components/stack/host/StackHost.web.d.ts +1 -3
  327. package/lib/typescript/components/stack/host/StackHost.web.d.ts.map +1 -1
  328. package/lib/typescript/components/stack/index.d.ts +4 -3
  329. package/lib/typescript/components/stack/index.d.ts.map +1 -1
  330. package/lib/typescript/components/tabs/host/TabsHost.d.ts +5 -0
  331. package/lib/typescript/components/tabs/host/TabsHost.d.ts.map +1 -0
  332. package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
  333. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +72 -0
  334. package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
  335. package/lib/typescript/components/tabs/host/TabsHost.types.d.ts +3 -0
  336. package/lib/typescript/components/tabs/host/TabsHost.types.d.ts.map +1 -1
  337. package/lib/typescript/components/tabs/index.d.ts +4 -6
  338. package/lib/typescript/components/tabs/index.d.ts.map +1 -1
  339. package/lib/typescript/components/tabs/screen/TabsScreen.android.d.ts.map +1 -1
  340. package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts +42 -7
  341. package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts.map +1 -1
  342. package/lib/typescript/components/tabs/screen/TabsScreen.d.ts +5 -0
  343. package/lib/typescript/components/tabs/screen/TabsScreen.d.ts.map +1 -0
  344. package/lib/typescript/components/tabs/screen/TabsScreen.ios.d.ts.map +1 -1
  345. package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts +78 -13
  346. package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts.map +1 -1
  347. package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts +91 -0
  348. package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts.map +1 -0
  349. package/lib/typescript/components/tabs/screen/index.d.ts +1 -0
  350. package/lib/typescript/components/tabs/screen/index.d.ts.map +1 -1
  351. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts +2 -0
  352. package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  353. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts +1 -0
  354. package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts.map +1 -1
  355. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +52 -0
  356. package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
  357. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +29 -1
  358. package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
  359. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +8 -0
  360. package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
  361. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +3 -1
  362. package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
  363. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +4 -0
  364. package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
  365. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts +6 -0
  366. package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts.map +1 -1
  367. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts +10 -1
  368. package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts.map +1 -1
  369. package/lib/typescript/legacy/components/ScreenStackItem.d.ts +25 -0
  370. package/lib/typescript/legacy/components/ScreenStackItem.d.ts.map +1 -1
  371. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts +4 -0
  372. package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts.map +1 -1
  373. package/lib/typescript/legacy/types.d.ts +30 -0
  374. package/lib/typescript/legacy/types.d.ts.map +1 -1
  375. package/package.json +11 -8
  376. package/react-native.config.js +3 -0
  377. package/src/components/modals/form-sheet/FormSheet.types.ts +1 -1
  378. package/src/components/stack/header/StackHeaderConfig.android.tsx +54 -43
  379. package/src/components/stack/header/StackHeaderConfig.android.types.ts +641 -24
  380. package/src/components/stack/header/StackHeaderConfig.ios.tsx +55 -17
  381. package/src/components/stack/header/StackHeaderConfig.ios.types.ts +384 -2
  382. package/src/components/stack/header/StackHeaderConfig.tsx +12 -0
  383. package/src/components/stack/header/StackHeaderConfig.types.ts +4 -2
  384. package/src/components/stack/header/ios/StackHeaderItem.ios.tsx +9 -1
  385. package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +7 -0
  386. package/src/components/stack/host/StackHost.tsx +12 -3
  387. package/src/components/stack/host/StackHost.types.ts +50 -0
  388. package/src/components/stack/host/StackHost.web.tsx +1 -4
  389. package/src/components/stack/index.ts +14 -1
  390. package/src/components/tabs/host/TabsHost.ios.tsx +3 -0
  391. package/src/components/tabs/host/TabsHost.ios.types.ts +76 -0
  392. package/src/components/tabs/host/TabsHost.tsx +7 -0
  393. package/src/components/tabs/host/TabsHost.types.ts +3 -0
  394. package/src/components/tabs/index.ts +9 -0
  395. package/src/components/tabs/screen/TabsScreen.android.tsx +8 -3
  396. package/src/components/tabs/screen/TabsScreen.android.types.ts +42 -7
  397. package/src/components/tabs/screen/TabsScreen.ios.tsx +22 -5
  398. package/src/components/tabs/screen/TabsScreen.ios.types.ts +79 -17
  399. package/src/components/tabs/screen/TabsScreen.tsx +7 -0
  400. package/src/components/tabs/screen/TabsScreenIcon.types.ts +117 -0
  401. package/src/components/tabs/screen/index.ts +1 -0
  402. package/src/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.ts +6 -0
  403. package/src/fabric/legacy/ScreenStackNativeComponent.ts +2 -0
  404. package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +78 -0
  405. package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +43 -0
  406. package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +13 -0
  407. package/src/fabric/stack/StackHostNativeComponent.ts +11 -2
  408. package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +8 -0
  409. package/src/fabric/tabs/TabsScreenAndroidNativeComponent.ts +9 -0
  410. package/src/fabric/tabs/TabsScreenIOSNativeComponent.ts +20 -2
  411. package/src/legacy/components/ScreenStackItem.tsx +59 -12
  412. package/src/legacy/types.ts +31 -0
  413. package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenModalFragment.kt +0 -281
  414. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogRootView.kt +0 -104
  415. package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogScreen.kt +0 -26
  416. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingView.kt +0 -83
  417. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewManager.kt +0 -89
  418. package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewPointerEvents.kt +0 -18
  419. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetDimensionsCoordinator.kt +0 -134
  420. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialogManager.kt +0 -162
  421. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/model/FormSheetDetents.kt +0 -106
  422. package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationManager.kt +0 -198
  423. package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +0 -83
  424. package/ios/conversion/RNSConversions-Stack.h +0 -32
  425. package/ios/conversion/RNSConversions-Stack.mm +0 -41
  426. package/ios/conversion/always_false.h +0 -31
  427. package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js +0 -10
  428. package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js.map +0 -1
  429. package/lib/commonjs/components/tabs/host/TabsHost.d.js +0 -2
  430. package/lib/commonjs/components/tabs/host/TabsHost.d.js.map +0 -1
  431. package/lib/commonjs/components/tabs/host/TabsHost.web.js.map +0 -1
  432. package/lib/commonjs/components/tabs/screen/TabsScreen.d.js +0 -2
  433. package/lib/commonjs/components/tabs/screen/TabsScreen.d.js.map +0 -1
  434. package/lib/commonjs/components/tabs/screen/TabsScreen.web.js.map +0 -1
  435. package/lib/module/components/stack/header/StackHeaderConfig.d.js +0 -2
  436. package/lib/module/components/stack/header/StackHeaderConfig.web.js +0 -4
  437. package/lib/module/components/stack/header/StackHeaderConfig.web.js.map +0 -1
  438. package/lib/module/components/tabs/host/TabsHost.d.js +0 -2
  439. package/lib/module/components/tabs/host/TabsHost.d.js.map +0 -1
  440. package/lib/module/components/tabs/host/TabsHost.web.js +0 -4
  441. package/lib/module/components/tabs/host/TabsHost.web.js.map +0 -1
  442. package/lib/module/components/tabs/screen/TabsScreen.d.js +0 -2
  443. package/lib/module/components/tabs/screen/TabsScreen.d.js.map +0 -1
  444. package/lib/module/components/tabs/screen/TabsScreen.web.js +0 -4
  445. package/lib/module/components/tabs/screen/TabsScreen.web.js.map +0 -1
  446. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts +0 -7
  447. package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts.map +0 -1
  448. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts +0 -7
  449. package/lib/typescript/components/tabs/host/TabsHost.web.d.ts.map +0 -1
  450. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts +0 -7
  451. package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts.map +0 -1
  452. package/src/components/stack/header/StackHeaderConfig.d.ts +0 -22
  453. package/src/components/stack/header/StackHeaderConfig.web.tsx +0 -5
  454. package/src/components/tabs/host/TabsHost.d.ts +0 -12
  455. package/src/components/tabs/screen/TabsScreen.d.ts +0 -12
  456. /package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.h +0 -0
@@ -0,0 +1,290 @@
1
+ package com.swmansion.rnscreens.core.modals.formsheet.presentation
2
+
3
+ import android.animation.Animator
4
+ import android.animation.AnimatorListenerAdapter
5
+ import android.util.Log
6
+ import android.view.View
7
+ import androidx.core.view.doOnPreDraw
8
+ import com.google.android.material.bottomsheet.BottomSheetBehavior
9
+ import com.swmansion.rnscreens.common.event.ViewAppearanceEventEmitter
10
+
11
+ internal class FormSheetPresentationManager(
12
+ private val presentationFactory: () -> FormSheetPresentation,
13
+ private val dimmingManager: FormSheetDimmingManager,
14
+ private val onNativeDismiss: () -> Unit,
15
+ private val onDismiss: () -> Unit,
16
+ ) {
17
+ internal var appearanceEventEmitter: ViewAppearanceEventEmitter? = null
18
+
19
+ internal var currentPresentation: FormSheetPresentation? = null
20
+ private set
21
+
22
+ private val bottomSheetView: View?
23
+ get() = currentPresentation?.bottomSheetView
24
+
25
+ private var state = FormSheetPresentationState.DISMISSED
26
+ private var shouldBeOpen = false
27
+ private var shouldSkipExitAnimation = false
28
+
29
+ private var dismissalOrigin = FormSheetDismissalOrigin.UNSPECIFIED
30
+
31
+ private val animatorFactory = FormSheetAnimatorFactory(dimmingManager)
32
+ private var currentSheetAnimator: Animator? = null
33
+
34
+ internal fun requestProgrammaticStateUpdate(shouldBeOpen: Boolean) {
35
+ if (shouldBeOpen) {
36
+ handlePresent()
37
+ } else {
38
+ handleProgrammaticDismiss()
39
+ }
40
+ }
41
+
42
+ private fun handlePresent() {
43
+ updatePresentationState(shouldBeOpen = true, origin = FormSheetDismissalOrigin.UNSPECIFIED)
44
+ }
45
+
46
+ private fun handleProgrammaticDismiss() {
47
+ updatePresentationState(shouldBeOpen = false, origin = FormSheetDismissalOrigin.PROGRAMMATIC_JS)
48
+ }
49
+
50
+ internal fun handleNativeDismiss() {
51
+ if (state == FormSheetPresentationState.DISMISSING || state == FormSheetPresentationState.DISMISSED) {
52
+ return
53
+ }
54
+
55
+ updatePresentationState(shouldBeOpen = false, origin = FormSheetDismissalOrigin.USER)
56
+ }
57
+
58
+ private fun updatePresentationState(
59
+ shouldBeOpen: Boolean,
60
+ origin: FormSheetDismissalOrigin,
61
+ ) {
62
+ // The origin belongs to the request that transitioned the target to closed -
63
+ // a repeated close request must not override it. Once a dismissal is in flight,
64
+ // it keeps the origin that started it until the completion events are emitted.
65
+ val isRepeatCloseRequest = !shouldBeOpen && !this.shouldBeOpen
66
+ if (state != FormSheetPresentationState.DISMISSING && !isRepeatCloseRequest) {
67
+ dismissalOrigin = origin
68
+ }
69
+ this.shouldBeOpen = shouldBeOpen
70
+ resolvePresentationState()
71
+ }
72
+
73
+ private fun resolvePresentationState() {
74
+ if (shouldBeOpen) {
75
+ presentIfNeeded()
76
+ } else {
77
+ dismissIfNeeded()
78
+ }
79
+ }
80
+
81
+ private fun presentIfNeeded() {
82
+ if (state != FormSheetPresentationState.DISMISSED) {
83
+ return
84
+ }
85
+
86
+ state = FormSheetPresentationState.PRESENTING
87
+ val presentation = presentationFactory().also { currentPresentation = it }
88
+ presentation.sheetBehavior?.let(dimmingManager::attachToBehavior)
89
+
90
+ FormSheetStackRegistry.register(this)
91
+ appearanceEventEmitter?.emitOnWillAppear()
92
+ presentation.bottomSheetView?.let(::keepOffscreenUntilEnterAnimation)
93
+ presentation.dialog.setOnShowListener {
94
+ presentation.dialog.setOnShowListener(null)
95
+
96
+ // Every sheet dims the surface inside the window below, attaching an overlay to the sheet
97
+ // directly below in the stack, or to the DecorView when this sheet is the
98
+ // bottom-most one.
99
+ dimmingManager.attachDimming(FormSheetStackRegistry.sheetBelow(this)?.bottomSheetView)
100
+
101
+ startEnterAnimation()
102
+ }
103
+ presentation.dialog.show()
104
+ }
105
+
106
+ private fun dismissIfNeeded() {
107
+ if (state != FormSheetPresentationState.PRESENTED) {
108
+ return
109
+ }
110
+
111
+ state = FormSheetPresentationState.DISMISSING
112
+ currentPresentation?.setKeyboardTrackingEnabled(false)
113
+ dismissSheetsAbove()
114
+ // Leaving the stack immediately is deliberate, if another sheet is presented during this exit animation,
115
+ // it must stack on a "stable" sheet - the one we don't intend to dismiss. This window is about to be
116
+ // torn down.
117
+ FormSheetStackRegistry.unregister(this)
118
+ appearanceEventEmitter?.emitOnWillDisappear()
119
+
120
+ val isSheetHidden =
121
+ bottomSheetView?.let {
122
+ BottomSheetBehavior.from(it).state == BottomSheetBehavior.STATE_HIDDEN
123
+ } ?: true
124
+
125
+ if (isSheetHidden) {
126
+ performDismiss()
127
+ return
128
+ }
129
+
130
+ if (shouldSkipExitAnimation) {
131
+ performInstantDismiss()
132
+ return
133
+ }
134
+
135
+ startExitAnimation()
136
+ }
137
+
138
+ // Dismissing a sheet from the middle of the stack should dismiss all sheets above it,
139
+ // mirroring the iOS presentation chain teardown. Sheets are dismissed top-down.
140
+ private fun dismissSheetsAbove() {
141
+ FormSheetStackRegistry.sheetsAbove(this).asReversed().forEach {
142
+ it.handleDismissFromCascade()
143
+ }
144
+ }
145
+
146
+ private fun handleDismissFromCascade() {
147
+ if (state == FormSheetPresentationState.DISMISSING || state == FormSheetPresentationState.DISMISSED) {
148
+ return
149
+ }
150
+
151
+ shouldSkipExitAnimation = true
152
+ updatePresentationState(false, FormSheetDismissalOrigin.USER)
153
+ }
154
+
155
+ private fun performInstantDismiss() {
156
+ currentSheetAnimator?.removeAllListeners()
157
+ currentSheetAnimator?.cancel()
158
+ currentSheetAnimator = null
159
+
160
+ performDismiss()
161
+ }
162
+
163
+ /**
164
+ * `Dialog.show()` **posts** the show message behind the sync barrier of the traversal scheduled while
165
+ * adding the decor to the window, so the Dialog always draws its first frame before `OnShowListener`
166
+ * (with our custom enter animation) runs. A freshly created sheet rests at `translationY = 0`, so that
167
+ * frame would show it at its final position and the enter animator would then snap it back
168
+ * off-screen.
169
+ *
170
+ * Applying the translation on the first pre-draw - after the layout, when the sheet height is
171
+ * already known, but before anything is drawn - keeps the sheet off-screen from the very first frame.
172
+ */
173
+ private fun keepOffscreenUntilEnterAnimation(view: View) {
174
+ view.doOnPreDraw {
175
+ if (currentSheetAnimator == null) {
176
+ view.translationY = view.height.toFloat()
177
+ }
178
+ }
179
+ }
180
+
181
+ private fun startEnterAnimation() {
182
+ val bottomSheetView = bottomSheetView
183
+ if (bottomSheetView == null) {
184
+ onPresentationComplete()
185
+ return
186
+ }
187
+
188
+ val isInterrupting = currentSheetAnimator?.isRunning == true
189
+ currentSheetAnimator?.removeAllListeners()
190
+ currentSheetAnimator?.cancel()
191
+
192
+ dimmingManager.isTransitionAnimationRunning = true
193
+
194
+ currentSheetAnimator =
195
+ animatorFactory.createEnterAnimator(bottomSheetView, isInterrupting).apply {
196
+ addListener(
197
+ object : AnimatorListenerAdapter() {
198
+ override fun onAnimationEnd(animation: Animator) {
199
+ dimmingManager.isTransitionAnimationRunning = false
200
+
201
+ if (currentSheetAnimator == this@apply) currentSheetAnimator = null
202
+ onPresentationComplete()
203
+ }
204
+ },
205
+ )
206
+ start()
207
+ }
208
+ }
209
+
210
+ private fun startExitAnimation() {
211
+ val bottomSheetView = bottomSheetView
212
+ if (bottomSheetView == null) {
213
+ performDismiss()
214
+ return
215
+ }
216
+
217
+ val isInterrupting = currentSheetAnimator?.isRunning == true
218
+ currentSheetAnimator?.removeAllListeners()
219
+ currentSheetAnimator?.cancel()
220
+
221
+ dimmingManager.isTransitionAnimationRunning = true
222
+
223
+ currentSheetAnimator =
224
+ animatorFactory.createExitAnimator(bottomSheetView, isInterrupting).apply {
225
+ addListener(
226
+ object : AnimatorListenerAdapter() {
227
+ override fun onAnimationEnd(animation: Animator) {
228
+ dimmingManager.isTransitionAnimationRunning = false
229
+
230
+ if (currentSheetAnimator == this@apply) currentSheetAnimator = null
231
+ performDismiss()
232
+ }
233
+ },
234
+ )
235
+ start()
236
+ }
237
+ }
238
+
239
+ private fun performDismiss() {
240
+ shouldSkipExitAnimation = false
241
+ dimmingManager.detachDimming()
242
+ currentPresentation?.destroy()
243
+ currentPresentation = null
244
+ onDismissComplete()
245
+ }
246
+
247
+ private fun onPresentationComplete() {
248
+ if (state == FormSheetPresentationState.PRESENTING) {
249
+ state = FormSheetPresentationState.PRESENTED
250
+ currentPresentation?.setKeyboardTrackingEnabled(true)
251
+ appearanceEventEmitter?.emitOnDidAppear()
252
+ // ensure state hasn't updated during presentation
253
+ resolvePresentationState()
254
+ }
255
+ }
256
+
257
+ private fun onDismissComplete() {
258
+ if (state == FormSheetPresentationState.DISMISSING) {
259
+ state = FormSheetPresentationState.DISMISSED
260
+ appearanceEventEmitter?.emitOnDidDisappear()
261
+
262
+ when (dismissalOrigin) {
263
+ FormSheetDismissalOrigin.USER -> onNativeDismiss()
264
+ FormSheetDismissalOrigin.PROGRAMMATIC_JS -> onDismiss()
265
+ FormSheetDismissalOrigin.UNSPECIFIED ->
266
+ Log.e(
267
+ "[RNScreens]",
268
+ "FormSheet dismissal completed without a recorded origin; no dismissal event emitted",
269
+ )
270
+ }
271
+ dismissalOrigin = FormSheetDismissalOrigin.UNSPECIFIED
272
+
273
+ // ensure state hasn't updated during dismissal
274
+ resolvePresentationState()
275
+ }
276
+ }
277
+
278
+ internal fun destroy() {
279
+ FormSheetStackRegistry.unregister(this)
280
+ dimmingManager.detachDimming()
281
+
282
+ currentSheetAnimator?.cancel()
283
+ currentSheetAnimator = null
284
+
285
+ currentPresentation?.destroy()
286
+ currentPresentation = null
287
+
288
+ state = FormSheetPresentationState.DISMISSED
289
+ }
290
+ }
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.modals.formsheet.native.presentation
1
+ package com.swmansion.rnscreens.core.modals.formsheet.presentation
2
2
 
3
3
  internal enum class FormSheetPresentationState {
4
4
  /**
@@ -27,7 +27,7 @@ internal enum class FormSheetPresentationState {
27
27
  /**
28
28
  * The manager is actively preparing to show the sheet. `presentIfNeeded()` has been called.
29
29
  * During this state, `dialog.show()` is executed. The manager waits for the `onShowListener`
30
- * to fire, requests DimmingView attachment from `dimmingManager` and runs starts entrance animation.
30
+ * to fire, attaches the dimming through `dimmingManager` and starts the entrance animation.
31
31
  * Once the enter animator finishes, the state moves to [PRESENTED].
32
32
  * **Transitional state** from [DISMISSED] to [PRESENTED].
33
33
  */
@@ -0,0 +1,28 @@
1
+ package com.swmansion.rnscreens.core.modals.formsheet.presentation
2
+
3
+ internal object FormSheetStackRegistry {
4
+ private val stack = mutableListOf<FormSheetPresentationManager>()
5
+
6
+ internal fun register(sheet: FormSheetPresentationManager) {
7
+ if (!stack.contains(sheet)) {
8
+ stack.add(sheet)
9
+ }
10
+ }
11
+
12
+ internal fun unregister(sheet: FormSheetPresentationManager) {
13
+ stack.remove(sheet)
14
+ }
15
+
16
+ internal fun sheetsAbove(sheet: FormSheetPresentationManager): List<FormSheetPresentationManager> {
17
+ val index = stack.indexOf(sheet)
18
+ if (index < 0) {
19
+ return emptyList()
20
+ }
21
+ return stack.drop(index + 1)
22
+ }
23
+
24
+ internal fun sheetBelow(sheet: FormSheetPresentationManager): FormSheetPresentationManager? {
25
+ val index = stack.indexOf(sheet)
26
+ return if (index > 0) stack[index - 1] else null
27
+ }
28
+ }
@@ -0,0 +1,6 @@
1
+ package com.swmansion.rnscreens.ext
2
+
3
+ import androidx.fragment.app.FragmentManager
4
+ import androidx.fragment.app.FragmentTransaction
5
+
6
+ internal fun FragmentManager.createTransactionWithReordering(): FragmentTransaction = this.beginTransaction().setReorderingAllowed(true)
@@ -6,7 +6,6 @@ import android.view.ViewParent
6
6
  import androidx.fragment.app.Fragment
7
7
  import androidx.fragment.app.FragmentActivity
8
8
  import androidx.fragment.app.FragmentManager
9
- import androidx.fragment.app.FragmentTransaction
10
9
  import com.facebook.react.ReactRootView
11
10
  import com.swmansion.rnscreens.common.FragmentProviding
12
11
 
@@ -75,5 +74,3 @@ object FragmentManagerHelper {
75
74
  }
76
75
  }
77
76
  }
78
-
79
- internal fun FragmentManager.createTransactionWithReordering(): FragmentTransaction = this.beginTransaction().setReorderingAllowed(true)
@@ -0,0 +1,31 @@
1
+ package com.swmansion.rnscreens.helpers
2
+
3
+ import android.content.res.ColorStateList
4
+ import android.content.res.Resources
5
+ import android.graphics.PorterDuff
6
+ import android.graphics.drawable.Drawable
7
+ import androidx.appcompat.graphics.drawable.DrawableWrapperCompat
8
+
9
+ // Ignores tinting so the wrapped icon keeps its own colors even when a host view
10
+ // (e.g. BottomNavigationView) applies an itemIconTintList.
11
+ internal class NoTintDrawable(
12
+ drawable: Drawable,
13
+ ) : DrawableWrapperCompat(drawable) {
14
+ override fun setTintList(tint: ColorStateList?) = Unit
15
+
16
+ override fun setTint(tintColor: Int) = Unit
17
+
18
+ override fun setTintMode(tintMode: PorterDuff.Mode?) = Unit
19
+
20
+ override fun getConstantState(): ConstantState? = drawable?.constantState?.let(::NoTintConstantState)
21
+
22
+ private class NoTintConstantState(
23
+ private val wrappedState: ConstantState,
24
+ ) : ConstantState() {
25
+ override fun newDrawable(): Drawable = NoTintDrawable(wrappedState.newDrawable())
26
+
27
+ override fun newDrawable(res: Resources?): Drawable = NoTintDrawable(wrappedState.newDrawable(res))
28
+
29
+ override fun getChangingConfigurations(): Int = wrappedState.changingConfigurations
30
+ }
31
+ }
@@ -1,6 +1,5 @@
1
1
  package com.swmansion.rnscreens.helpers
2
2
 
3
- import android.content.Context
4
3
  import android.graphics.drawable.Drawable
5
4
 
6
5
  /**
@@ -21,27 +20,28 @@ internal sealed interface IconResolution {
21
20
 
22
21
  /**
23
22
  * Stateful, latest-wins icon resolver for a single declaratively-driven icon slot — a `toolbarMenu`
24
- * prop menu item, or the back button — that is re-evaluated on every prop transaction. It
25
- * deduplicates unchanged sources ([IconResolution.Unchanged]) to avoid needless reloads/flicker,
26
- * and drops stale async results so a slow load cannot clobber a newer source.
23
+ * prop menu item, or the back button — that is re-evaluated on every source change. It deduplicates
24
+ * unchanged sources ([IconResolution.Unchanged]) to avoid needless reloads/flicker, and drops stale
25
+ * async results so a slow load cannot clobber a newer source.
26
+ *
27
+ * [load] must invoke its completion callback exactly once — synchronously or asynchronously,
28
+ * always on the main thread — with the loaded drawable, or `null` when the source resolves to
29
+ * no icon or fails to load (see e.g. [resolveImage]).
27
30
  */
28
- internal class PropIconResolver {
31
+ internal class PropIconResolver(
32
+ private val load: (drawableIconResourceName: String?, imageIconUri: String?, onComplete: (Drawable?) -> Unit) -> Unit,
33
+ ) {
29
34
  private var lastDrawableName: String? = null
30
35
  private var lastImageUri: String? = null
31
36
  private var lastEmittedDrawableName: String? = null
32
37
  private var lastEmittedImageUri: String? = null
33
38
 
34
39
  /**
35
- * Resolves an icon from a drawable resource name or an image uri.
36
- *
37
- * The result is delivered to [onResult] synchronously for drawable resources and empty sources,
38
- * and asynchronously for image uris. For image uris, the callback is only invoked if the
39
- * resolved uri is still the latest requested source (stale requests are dropped). On a failed
40
- * image load the latest request still emits [IconResolution.Resolved] with a `null` drawable, so
41
- * the icon is cleared rather than left stale.
40
+ * Resolves an icon from a drawable resource name or an image uri. The result is delivered
41
+ * to [onResult] only if the requested source is still the latest one (stale async results
42
+ * are dropped).
42
43
  */
43
44
  fun resolve(
44
- context: Context,
45
45
  drawableIconResourceName: String?,
46
46
  imageIconUri: String?,
47
47
  onResult: (IconResolution) -> Unit,
@@ -56,16 +56,10 @@ internal class PropIconResolver {
56
56
  }
57
57
  lastEmittedDrawableName = drawableIconResourceName
58
58
  lastEmittedImageUri = imageIconUri
59
- when {
60
- drawableIconResourceName != null ->
61
- onResult(IconResolution.Resolved(getSystemDrawableResource(context, drawableIconResourceName)))
62
- imageIconUri != null ->
63
- loadImage(context, imageIconUri) { drawable ->
64
- if (imageIconUri == lastImageUri && lastDrawableName == null) {
65
- onResult(IconResolution.Resolved(drawable))
66
- }
67
- }
68
- else -> onResult(IconResolution.Resolved(null))
59
+ load(drawableIconResourceName, imageIconUri) { drawable ->
60
+ if (drawableIconResourceName == lastDrawableName && imageIconUri == lastImageUri) {
61
+ onResult(IconResolution.Resolved(drawable))
62
+ }
69
63
  }
70
64
  }
71
65
  }
@@ -5,7 +5,6 @@ import android.view.ViewGroup
5
5
  import android.widget.ScrollView
6
6
  import androidx.core.view.isNotEmpty
7
7
  import androidx.core.widget.NestedScrollView
8
- import com.swmansion.rnscreens.legacy.ScreenStack
9
8
 
10
9
  object ViewFinder {
11
10
  fun findScrollViewInFirstDescendantChain(view: View): ViewGroup? {
@@ -23,20 +22,4 @@ object ViewFinder {
23
22
 
24
23
  return null
25
24
  }
26
-
27
- fun findScreenStackInFirstDescendantChain(view: View): ScreenStack? {
28
- var currentView: View? = view
29
-
30
- while (currentView != null) {
31
- if (currentView is ScreenStack) {
32
- return currentView
33
- } else if (currentView is ViewGroup && currentView.isNotEmpty()) {
34
- currentView = currentView.getChildAt(0)
35
- } else {
36
- break
37
- }
38
- }
39
-
40
- return null
41
- }
42
25
  }
@@ -27,6 +27,9 @@ import com.google.android.material.shape.CornerFamily
27
27
  import com.google.android.material.shape.MaterialShapeDrawable
28
28
  import com.google.android.material.shape.ShapeAppearanceModel
29
29
  import com.swmansion.rnscreens.common.FragmentProviding
30
+ import com.swmansion.rnscreens.common.container.Container
31
+ import com.swmansion.rnscreens.common.container.ContainerItem
32
+ import com.swmansion.rnscreens.common.container.ContainerItemSupport
30
33
  import com.swmansion.rnscreens.legacy.bottomsheet.SheetAnimationCoordinator
31
34
  import com.swmansion.rnscreens.legacy.bottomsheet.SheetDetents
32
35
  import com.swmansion.rnscreens.legacy.bottomsheet.fitToContentsSheetHeight
@@ -46,7 +49,10 @@ class Screen(
46
49
  val reactContext: ThemedReactContext,
47
50
  ) : FabricEnabledViewGroup(reactContext),
48
51
  ScreenContentWrapper.OnLayoutCallback,
49
- FragmentProviding {
52
+ FragmentProviding,
53
+ ContainerItem {
54
+ private val containerItemSupport = ContainerItemSupport()
55
+
50
56
  val fragment: Fragment?
51
57
  get() = fragmentWrapper?.fragment
52
58
 
@@ -236,7 +242,7 @@ class Screen(
236
242
  ) {
237
243
  // In case of form sheet we get layout notification a bit later, in `onBottomSheetBehaviorDidLayout`
238
244
  // after the attached behaviour laid out this view.
239
- if (changed && isNativeStackScreen && !usesFormSheetPresentation()) {
245
+ if ((changed || isStateInvalidated) && isNativeStackScreen && !usesFormSheetPresentation()) {
240
246
  val width = r - l
241
247
  val height = b - t
242
248
 
@@ -495,8 +501,10 @@ class Screen(
495
501
  // It has a custom `getChildDrawingOrder` method which returns
496
502
  // wrong index if we called `startViewTransition` on the views on new arch.
497
503
  // We add a simple View to bump the number of children to make it work.
504
+ // Appended, not inserted at `i`: a filler before the circle inflates the
505
+ // index `onMeasure` caches for it, which then outlives the child it points at.
498
506
  // TODO: find a better way to handle this scenario
499
- it.addView(View(context), i)
507
+ it.addView(View(context))
500
508
  } else {
501
509
  child?.let { view -> it.startViewTransition(view) }
502
510
  }
@@ -563,6 +571,13 @@ class Screen(
563
571
  updateShadowNodeScreenSize(width, height, top + translationY.toInt())
564
572
  }
565
573
 
574
+ override fun onDetachedFromWindow() {
575
+ super.onDetachedFromWindow()
576
+ // Rotation may reset the shadow state while this screen is covered. Republish it on the
577
+ // next layout, even if the native frame is identical to the one before detaching.
578
+ invalidateState()
579
+ }
580
+
566
581
  override fun onAttachedToWindow() {
567
582
  super.onAttachedToWindow()
568
583
 
@@ -617,6 +632,20 @@ class Screen(
617
632
  }
618
633
  }
619
634
 
635
+ // region ContainerItem
636
+
637
+ override fun registerNestedContainer(container: Container) = containerItemSupport.registerNestedContainer(container)
638
+
639
+ override fun unregisterNestedContainer(container: Container) = containerItemSupport.unregisterNestedContainer(container)
640
+
641
+ override fun resolveNestedContainer(): Container? = containerItemSupport.resolveNestedContainer()
642
+
643
+ override fun findContentScrollView(): ViewGroup? = containerItemSupport.findContentScrollView(this)
644
+
645
+ override fun wantsToPreventStackNativeDismiss(): ContainerItem? = resolveNestedContainer()?.wantsToPreventStackNativeDismiss()
646
+
647
+ // endregion
648
+
620
649
  enum class StackPresentation {
621
650
  PUSH,
622
651
  MODAL,
@@ -17,11 +17,15 @@ import com.facebook.react.modules.core.ReactChoreographer
17
17
  import com.facebook.react.uimanager.ThemedReactContext
18
18
  import com.facebook.react.uimanager.UIManagerHelper
19
19
  import com.swmansion.rnscreens.common.FragmentProviding
20
+ import com.swmansion.rnscreens.common.container.Container
21
+ import com.swmansion.rnscreens.common.container.ContainerItem
22
+ import com.swmansion.rnscreens.common.container.ParentContainerItemRegistry
20
23
  import com.swmansion.rnscreens.legacy.events.ScreenDismissedEvent
21
24
 
22
25
  open class ScreenContainer(
23
26
  context: Context?,
24
- ) : ViewGroup(context) {
27
+ ) : ViewGroup(context),
28
+ Container {
25
29
  @JvmField
26
30
  protected val screenWrappers = ArrayList<ScreenFragmentWrapper>()
27
31
 
@@ -43,6 +47,10 @@ open class ScreenContainer(
43
47
  }
44
48
  private var parentScreenWrapper: ScreenFragmentWrapper? = null
45
49
 
50
+ private val parentContainerRegistry = ParentContainerItemRegistry()
51
+
52
+ override fun shouldDelayChildPressedState(): Boolean = false
53
+
46
54
  override fun onLayout(
47
55
  changed: Boolean,
48
56
  l: Int,
@@ -275,16 +283,27 @@ open class ScreenContainer(
275
283
 
276
284
  override fun onAttachedToWindow() {
277
285
  super.onAttachedToWindow()
286
+ parentContainerRegistry.attach(this)
278
287
  isAttached = true
279
288
  setupFragmentManager()
280
289
  }
281
290
 
282
- /** Removes fragments from fragment manager that are attached to this container */
291
+ /**
292
+ * Removes fragments from fragment manager that are attached to this container, including
293
+ * fragments of screens already removed from it whose deferred removal hasn't run yet.
294
+ */
283
295
  private fun removeMyFragments(fragmentManager: FragmentManager) {
284
296
  val transaction = fragmentManager.beginTransaction()
285
297
  var hasFragments = false
286
298
  for (fragment in fragmentManager.fragments) {
287
- if (fragment is ScreenFragment && fragment.screen.container === this) {
299
+ // `removeScreenAt` / `removeAllScreens` clear `screen.container` immediately but defer
300
+ // the fragment removal, so also match such orphans by the container view id.
301
+ if (fragment is ScreenFragment &&
302
+ (
303
+ fragment.screen.container === this ||
304
+ (fragment.screen.container == null && fragment.id == id)
305
+ )
306
+ ) {
288
307
  transaction.remove(fragment)
289
308
  hasFragments = true
290
309
  }
@@ -310,6 +329,7 @@ open class ScreenContainer(
310
329
 
311
330
  parentScreenWrapper?.removeChildScreenContainer(this)
312
331
  parentScreenWrapper = null
332
+ parentContainerRegistry.detach(this)
313
333
 
314
334
  super.onDetachedFromWindow()
315
335
  isAttached = false
@@ -444,4 +464,16 @@ open class ScreenContainer(
444
464
  protected open fun notifyContainerUpdate() {
445
465
  topScreen?.fragmentWrapper?.onContainerUpdate()
446
466
  }
467
+
468
+ // region Container
469
+
470
+ // Only the currently shown (top) screen is consulted.
471
+ override fun resolveCurrentContentScrollView(): ViewGroup? = topScreen?.findContentScrollView()
472
+
473
+ override fun wantsToPreventStackNativeDismiss(): ContainerItem? = topScreen?.wantsToPreventStackNativeDismiss()
474
+
475
+ // Nothing to pop here - the request goes to the shown screen's nested container.
476
+ override fun requestPopToRoot(): Boolean = topScreen?.resolveNestedContainer()?.requestPopToRoot() == true
477
+
478
+ // endregion
447
479
  }
@@ -6,6 +6,7 @@ import android.os.Build
6
6
  import android.view.View
7
7
  import com.facebook.react.bridge.ReactContext
8
8
  import com.facebook.react.uimanager.UIManagerHelper
9
+ import com.swmansion.rnscreens.common.container.ContainerItem
9
10
  import com.swmansion.rnscreens.legacy.bottomsheet.requiresEnterTransitionPostponing
10
11
  import com.swmansion.rnscreens.legacy.bottomsheet.sheetShouldUseDimmingView
11
12
  import com.swmansion.rnscreens.legacy.bottomsheet.usesFormSheetPresentation
@@ -282,6 +283,8 @@ class ScreenStack(
282
283
  screenWrappers
283
284
  .asSequence()
284
285
  .dropWhile { it !== visibleBottom } // ignore all screens beneath the visible bottom
286
+ // dismissed screens are already removed above & preloaded ones must stay detached
287
+ .filter { !dismissedWrappers.contains(it) && it.screen.activityState !== Screen.ActivityState.INACTIVE }
285
288
  .forEach { wrapper ->
286
289
  // TODO: It should be enough to dispatch this on commit action once.
287
290
  transaction.add(id, wrapper.fragment).runOnCommit {
@@ -438,6 +441,18 @@ class ScreenStack(
438
441
  }
439
442
  }
440
443
 
444
+ // region Container
445
+
446
+ override fun wantsToPreventStackNativeDismiss(): ContainerItem? =
447
+ screenWrappers
448
+ .asReversed()
449
+ .filter { !dismissedWrappers.contains(it) }
450
+ .firstNotNullOfOrNull { it.screen.wantsToPreventStackNativeDismiss() }
451
+
452
+ override fun requestPopToRoot(): Boolean = popToRoot() || super.requestPopToRoot()
453
+
454
+ // endregion
455
+
441
456
  companion object {
442
457
  const val TAG = "ScreenStack"
443
458