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,107 @@
1
+ package com.swmansion.rnscreens.core.modals.formsheet.dialog
2
+
3
+ import android.app.Activity
4
+ import android.content.Context
5
+ import android.content.ContextWrapper
6
+ import android.view.ContextThemeWrapper
7
+ import android.view.View
8
+ import com.swmansion.rnscreens.core.modals.formsheet.interfaces.FormSheetContentSizeChangeDelegate
9
+ import com.swmansion.rnscreens.core.modals.formsheet.interfaces.FormSheetDialogEventEmitter
10
+ import com.swmansion.rnscreens.core.modals.formsheet.model.FormSheetConfig
11
+ import com.swmansion.rnscreens.core.modals.formsheet.presentation.FormSheetDimmingManager
12
+ import com.swmansion.rnscreens.core.modals.formsheet.presentation.FormSheetPresentation
13
+ import com.swmansion.rnscreens.core.modals.formsheet.presentation.FormSheetPresentationManager
14
+ import kotlin.properties.Delegates
15
+
16
+ /**
17
+ * @param activityProvider returns the activity whose decor view hosts the sheet's dimming. The default walks the
18
+ * [ContextWrapper] chain of [context]; hosts whose context does not wrap an activity must provide their own.
19
+ */
20
+ class FormSheetDialogManager(
21
+ context: Context,
22
+ private val contentView: View,
23
+ activityProvider: () -> Activity? = { context.findActivity() },
24
+ ) {
25
+ private var formSheetConfig = FormSheetConfig()
26
+
27
+ private val themedContext =
28
+ ContextThemeWrapper(
29
+ context,
30
+ com.google.android.material.R.style.Theme_Material3_DayNight_NoActionBar,
31
+ )
32
+
33
+ // Eagerly create the container so it's always ready for the provided content view
34
+ private val container = FormSheetContainer(themedContext, contentView)
35
+
36
+ // The React content only reports height changes, so a new presentation is seeded with the
37
+ // last known value.
38
+ private var lastContentHeight = 0
39
+
40
+ private val presentationCallbacks =
41
+ object : FormSheetPresentation.Callbacks {
42
+ override fun onDetentChanged(index: Int) {
43
+ eventEmitter?.emitOnDetentChanged(index)
44
+ }
45
+
46
+ override fun onNativeDismissAllowed() {
47
+ presentationManager.handleNativeDismiss()
48
+ }
49
+
50
+ override fun onNativeDismissPrevented() {
51
+ eventEmitter?.emitOnNativeDismissPreventedEvent()
52
+ }
53
+ }
54
+
55
+ private val dimmingManager = FormSheetDimmingManager(activityProvider)
56
+
57
+ private val presentationManager =
58
+ FormSheetPresentationManager(
59
+ presentationFactory = ::createPresentation,
60
+ dimmingManager = dimmingManager,
61
+ onNativeDismiss = { eventEmitter?.emitOnNativeDismissEvent() },
62
+ onDismiss = { eventEmitter?.emitOnDismissEvent() },
63
+ )
64
+
65
+ internal var eventEmitter: FormSheetDialogEventEmitter? by Delegates.observable(null) { _, _, newValue ->
66
+ presentationManager.appearanceEventEmitter = newValue
67
+ }
68
+
69
+ internal val contentSizeChangeDelegate: FormSheetContentSizeChangeDelegate =
70
+ object : FormSheetContentSizeChangeDelegate {
71
+ override fun onContentHeightChanged(newHeight: Int) {
72
+ lastContentHeight = newHeight
73
+ presentationManager.currentPresentation?.onContentHeightChanged(newHeight)
74
+ }
75
+ }
76
+
77
+ private fun createPresentation(): FormSheetPresentation =
78
+ FormSheetPresentation(themedContext, container, presentationCallbacks).also {
79
+ it.applyInitialConfig(formSheetConfig, lastContentHeight)
80
+ }
81
+
82
+ internal fun applyConfig(newConfig: FormSheetConfig) {
83
+ val oldConfig = formSheetConfig
84
+ formSheetConfig = newConfig
85
+
86
+ presentationManager.currentPresentation?.applyConfigUpdate(oldConfig, newConfig)
87
+
88
+ if (oldConfig.isOpen != newConfig.isOpen) {
89
+ presentationManager.requestProgrammaticStateUpdate(newConfig.isOpen)
90
+ }
91
+ }
92
+
93
+ internal fun destroy() {
94
+ presentationManager.destroy()
95
+ }
96
+ }
97
+
98
+ private fun Context.findActivity(): Activity? {
99
+ var current: Context? = this
100
+ while (current is ContextWrapper) {
101
+ if (current is Activity) {
102
+ return current
103
+ }
104
+ current = current.baseContext
105
+ }
106
+ return null
107
+ }
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.modals.formsheet.native.interfaces
1
+ package com.swmansion.rnscreens.core.modals.formsheet.interfaces
2
2
 
3
3
  interface FormSheetContentSizeChangeDelegate {
4
4
  fun onContentHeightChanged(newHeight: Int)
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.modals.formsheet.native.interfaces
1
+ package com.swmansion.rnscreens.core.modals.formsheet.interfaces
2
2
 
3
3
  interface FormSheetContentSizeChangeProvider {
4
4
  fun setContentSizeChangeDelegate(delegate: FormSheetContentSizeChangeDelegate?)
@@ -1,8 +1,10 @@
1
- package com.swmansion.rnscreens.modals.formsheet.native.interfaces
1
+ package com.swmansion.rnscreens.core.modals.formsheet.interfaces
2
2
 
3
3
  import com.swmansion.rnscreens.common.event.ViewAppearanceEventEmitter
4
4
 
5
5
  internal interface FormSheetDialogEventEmitter : ViewAppearanceEventEmitter {
6
+ fun emitOnDismissEvent()
7
+
6
8
  fun emitOnNativeDismissEvent()
7
9
 
8
10
  fun emitOnNativeDismissPreventedEvent()
@@ -1,4 +1,4 @@
1
- package com.swmansion.rnscreens.modals.formsheet.native.model
1
+ package com.swmansion.rnscreens.core.modals.formsheet.model
2
2
 
3
3
  internal data class FormSheetConfig(
4
4
  val isOpen: Boolean = false,
@@ -0,0 +1,152 @@
1
+ package com.swmansion.rnscreens.core.modals.formsheet.model
2
+
3
+ import kotlin.math.roundToInt
4
+
5
+ internal class FormSheetDetents(
6
+ rawDetents: List<Double>,
7
+ ) {
8
+ private val detents: List<Double> = rawDetents.toList()
9
+
10
+ init {
11
+ require(detents.isNotEmpty()) { "[RNScreens] At least one detent must be provided." }
12
+ require(detents.size <= MAX_DETENTS) { "[RNScreens] Maximum of $MAX_DETENTS detents supported, got ${detents.size}." }
13
+
14
+ // Valid fitToContents configuration is a single detent with value -1.0.
15
+ // For any other configuration, we should validate provided detents array.
16
+ if (!isFitToContents) {
17
+ detents.forEach {
18
+ require(it in 0.0..1.0) {
19
+ "[RNScreens] Detent values must be within 0.0 and 1.0, got $it."
20
+ }
21
+ }
22
+
23
+ require(detents == detents.distinct().sorted()) {
24
+ "[RNScreens] Detents must be sorted in strictly ascending order."
25
+ }
26
+ }
27
+ }
28
+
29
+ internal val isFitToContents: Boolean
30
+ get() = detents.size == 1 && detents[0] == FIT_TO_CONTENTS_DETENT_VALUE
31
+
32
+ internal val count: Int get() = detents.size
33
+
34
+ private fun heightFractionAt(index: Int): Double = detents[index]
35
+
36
+ // Height of the sheet resting at the given detent, measured down to the bottom edge of the container.
37
+ private fun heightAt(
38
+ index: Int,
39
+ containerHeight: Int,
40
+ keyboardLift: Int,
41
+ ): Int = ((heightFractionAt(index) * containerHeight).roundToInt() + keyboardLift).coerceAtMost(containerHeight)
42
+
43
+ /**
44
+ * Height handed to Material as `peekHeight`. Material treats the peek height as the content height above
45
+ * the bottom inset and adds that inset back (`BottomSheetBehavior.calculatePeekHeight`), while every
46
+ * other metric (`maxHeight`, `halfExpandedRatio`) describes the sheet down to the screen edge. The inset is
47
+ * subtracted here so the lowest detent is resolved against the same reference as the other ones.
48
+ * Material's inset covers the keyboard as well, so the lift is subtracted along with the system inset.
49
+ */
50
+ internal fun peekHeight(
51
+ containerHeight: Int,
52
+ bottomInset: Int,
53
+ keyboardLift: Int = 0,
54
+ ): Int = (heightAt(0, containerHeight, keyboardLift) - bottomInset - keyboardLift).coerceAtLeast(0)
55
+
56
+ internal fun maxAllowedHeight(
57
+ containerHeight: Int,
58
+ keyboardLift: Int = 0,
59
+ ): Int = heightAt(count - 1, containerHeight, keyboardLift)
60
+
61
+ internal fun maxAllowedHeightForFitToContents(
62
+ containerHeight: Int,
63
+ contentHeight: Int,
64
+ bottomInset: Int,
65
+ keyboardLift: Int = 0,
66
+ ): Int {
67
+ /*
68
+ * We add the `bottomInset` and the `keyboardLift` to the `contentHeight` so that the Material BottomSheet
69
+ * is laid out behind the system navigation bar or the keyboard. The sheet's container covers the insets,
70
+ * while the RN content is strictly constrained to `contentHeight`.
71
+ */
72
+ if (contentHeight <= 0) {
73
+ // Avoid collapsing the sheet before the React content has been laid out and measured.
74
+ return containerHeight
75
+ }
76
+ return (contentHeight + bottomInset + keyboardLift).coerceAtMost(containerHeight)
77
+ }
78
+
79
+ /**
80
+ * Ratio of the middle detent's sheet height to the container height, handed to Material as `halfExpandedRatio`.
81
+ * Material resolves the half-expanded position from it as `(int) (parentHeight * (1 - ratio))`.
82
+ *
83
+ * The keyboard lift can push both the middle and the largest detent to the top of the container. Material needs
84
+ * the half-expanded position strictly below the expanded one so the middle detent is kept at least
85
+ * [MIDDLE_DETENT_MIN_GAP] px shorter than the largest one.
86
+ */
87
+ internal fun halfExpandedRatio(
88
+ containerHeight: Int,
89
+ keyboardLift: Int = 0,
90
+ ): Float {
91
+ check(count == MAX_DETENTS) { "[RNScreens] Exactly $MAX_DETENTS detents are required for halfExpandedRatio." }
92
+ val middleDetentHeight =
93
+ heightAt(1, containerHeight, keyboardLift)
94
+ .coerceAtMost(maxAllowedHeight(containerHeight, keyboardLift) - MIDDLE_DETENT_MIN_GAP)
95
+ .coerceAtLeast(1)
96
+ return middleDetentHeight.toFloat() / containerHeight
97
+ }
98
+
99
+ internal fun expandedOffsetFromTop(
100
+ containerHeight: Int,
101
+ topInset: Int = 0,
102
+ keyboardLift: Int = 0,
103
+ ): Int {
104
+ check(count == MAX_DETENTS) { "[RNScreens] Exactly $MAX_DETENTS detents are required for expandedOffsetFromTop." }
105
+ return largestDetentTopOffset(containerHeight, keyboardLift) + topInset
106
+ }
107
+
108
+ // Distance from the top of the window to the top of the largest detent's surface.
109
+ private fun largestDetentTopOffset(
110
+ containerHeight: Int,
111
+ keyboardLift: Int,
112
+ ): Int = containerHeight - maxAllowedHeight(containerHeight, keyboardLift)
113
+
114
+ /**
115
+ * Material's BottomSheetDialog dynamically applies padding when its content overlaps
116
+ * system insets. To prevent recalculating the size, we pre-calculate a static height
117
+ * inside safe area bounds.
118
+ */
119
+ internal fun sheetContainerHeight(
120
+ containerHeight: Int,
121
+ topInset: Int,
122
+ bottomInset: Int,
123
+ contentHeight: Int = 0,
124
+ keyboardLift: Int = 0,
125
+ ): Int {
126
+ val bottomPadding = bottomInset + keyboardLift
127
+
128
+ if (isFitToContents) {
129
+ // Until we have a measured content height, fall back to a safe-area height so Yoga can lay out.
130
+ if (contentHeight <= 0) {
131
+ return (containerHeight - topInset - bottomPadding).coerceAtLeast(0)
132
+ }
133
+ // Content taller than the safe area is aligned with it.
134
+ return contentHeight.coerceAtMost((containerHeight - topInset - bottomPadding).coerceAtLeast(0))
135
+ }
136
+
137
+ // Bottom padding is always fully subtracted because the sheet is in its dedicated window and it's
138
+ // anchored to the bottom.
139
+ // Top inset is subtracted only by the amount the sheet actually overlaps it.
140
+ val topOverlap = (topInset - largestDetentTopOffset(containerHeight, keyboardLift)).coerceAtLeast(0)
141
+ return (maxAllowedHeight(containerHeight, keyboardLift) - topOverlap - bottomPadding).coerceAtLeast(0)
142
+ }
143
+
144
+ companion object {
145
+ const val MAX_DETENTS = 3
146
+ const val FIT_TO_CONTENTS_DETENT_VALUE = -1.0
147
+
148
+ // Material resolves the half-expanded position in float precision and the truncation to int can eat 1 px
149
+ // which would put the middle detent back on the expanded position.
150
+ private const val MIDDLE_DETENT_MIN_GAP = 2
151
+ }
152
+ }
@@ -1,14 +1,12 @@
1
- package com.swmansion.rnscreens.modals.formsheet.native.presentation
1
+ package com.swmansion.rnscreens.core.modals.formsheet.presentation
2
2
 
3
3
  import android.animation.Animator
4
4
  import android.animation.AnimatorSet
5
5
  import android.animation.ValueAnimator
6
6
  import android.view.View
7
- import androidx.core.animation.doOnStart
8
- import com.swmansion.rnscreens.modals.dimmingview.DimmingViewManager
9
7
 
10
8
  internal class FormSheetAnimatorFactory(
11
- private val dimmingManager: DimmingViewManager,
9
+ private val dimmingManager: FormSheetDimmingManager,
12
10
  ) {
13
11
  // TODO: @t0maboro - consider exposing as a prop
14
12
  val animationDuration = 250L
@@ -18,7 +16,7 @@ internal class FormSheetAnimatorFactory(
18
16
  isInterrupting: Boolean = false,
19
17
  ): Animator {
20
18
  val startY = if (isInterrupting) view.translationY else view.height.toFloat()
21
- val startAlpha = if (isInterrupting) dimmingManager.dimmingViewAlpha else 0f
19
+ val startAlpha = if (isInterrupting) dimmingManager.dimmingAlpha else 0f
22
20
 
23
21
  val slideAnimator =
24
22
  ValueAnimator.ofFloat(startY, 0f).apply {
@@ -30,14 +28,13 @@ internal class FormSheetAnimatorFactory(
30
28
  val alphaAnimator =
31
29
  ValueAnimator.ofFloat(startAlpha, dimmingManager.maxAlpha).apply {
32
30
  addUpdateListener { animation ->
33
- dimmingManager.dimmingViewAlpha = animation.animatedValue as Float
31
+ dimmingManager.dimmingAlpha = animation.animatedValue as Float
34
32
  }
35
33
  }
36
34
 
37
35
  return AnimatorSet().apply {
38
36
  playTogether(slideAnimator, alphaAnimator)
39
37
  duration = animationDuration
40
- doOnStart { view.translationY = startY }
41
38
  }
42
39
  }
43
40
 
@@ -45,8 +42,10 @@ internal class FormSheetAnimatorFactory(
45
42
  view: View,
46
43
  isInterrupting: Boolean = false,
47
44
  ): Animator {
48
- val startY = if (isInterrupting) view.translationY else 0f
49
- val startAlpha = if (isInterrupting) dimmingManager.dimmingViewAlpha else dimmingManager.maxAlpha
45
+ // Always leave from the current translation: besides an interrupted enter animation, the sheet
46
+ // may be mid-way through tracking the keyboard animation when the dismissal starts.
47
+ val startY = view.translationY
48
+ val startAlpha = if (isInterrupting) dimmingManager.dimmingAlpha else dimmingManager.maxAlpha
50
49
 
51
50
  val slideAnimator =
52
51
  ValueAnimator.ofFloat(startY, view.height.toFloat()).apply {
@@ -58,7 +57,7 @@ internal class FormSheetAnimatorFactory(
58
57
  val alphaAnimator =
59
58
  ValueAnimator.ofFloat(startAlpha, 0f).apply {
60
59
  addUpdateListener { animation ->
61
- dimmingManager.dimmingViewAlpha = animation.animatedValue as Float
60
+ dimmingManager.dimmingAlpha = animation.animatedValue as Float
62
61
  }
63
62
  }
64
63
 
@@ -0,0 +1,103 @@
1
+ package com.swmansion.rnscreens.core.modals.formsheet.presentation
2
+
3
+ import android.app.Activity
4
+ import android.graphics.Color
5
+ import android.graphics.drawable.ColorDrawable
6
+ import android.util.Log
7
+ import android.view.View
8
+ import com.google.android.material.bottomsheet.BottomSheetBehavior
9
+ import kotlin.math.roundToInt
10
+
11
+ /**
12
+ * @param activityProvider returns the activity whose decor view hosts the dimming of the bottom-most sheet.
13
+ */
14
+ internal class FormSheetDimmingManager(
15
+ private val activityProvider: () -> Activity?,
16
+ ) {
17
+ // TODO: @t0maboro - consider exposing as a prop
18
+ internal val maxAlpha: Float = MAX_DIMMING_ALPHA_FRACTION
19
+
20
+ internal var isTransitionAnimationRunning: Boolean = false
21
+
22
+ // The drawable rendering this sheet's dimming, added to the overlay of dimmingHost which is
23
+ // Material's `design_bottom_sheet` component or the DecorView of the main application content.
24
+ private var dimmingDrawable: ColorDrawable? = null
25
+ private var dimmingHost: View? = null
26
+
27
+ private val dimmingHostLayoutListener =
28
+ View.OnLayoutChangeListener { view, _, _, _, _, _, _, _, _ ->
29
+ dimmingDrawable?.setBounds(0, 0, view.width, view.height)
30
+ }
31
+
32
+ internal var dimmingAlpha: Float = 0f
33
+ set(value) {
34
+ field = value
35
+ // We're transforming the value, because View.alpha is within [0.0, 1.0] range,
36
+ // while Drawable.alpha is an Integer in [0, 255] range.
37
+ dimmingDrawable?.alpha = (value * MAX_DRAWABLE_OVERLAY_ALPHA).roundToInt().coerceIn(0, MAX_DRAWABLE_OVERLAY_ALPHA)
38
+ }
39
+
40
+ /**
41
+ * Called when the sheet is presented. [belowSheetView] is the `design_bottom_sheet` of the
42
+ * sheet directly below in the stack, or null when this sheet is the bottom-most one - the
43
+ * dimming then goes onto the decor of the activity hosting the sheets.
44
+ */
45
+ internal fun attachDimming(belowSheetView: View?) {
46
+ val host = belowSheetView ?: resolveActivityDecorView()
47
+ if (host == null) {
48
+ Log.e(TAG, "[RNScreens] Neither a sheet below nor an activity decor found; the sheet will present undimmed.")
49
+ return
50
+ }
51
+
52
+ dimmingHost = host
53
+ dimmingDrawable =
54
+ ColorDrawable(Color.BLACK).apply {
55
+ alpha = 0
56
+ setBounds(0, 0, host.width, host.height)
57
+ }
58
+ host.overlay.add(dimmingDrawable!!)
59
+ host.addOnLayoutChangeListener(dimmingHostLayoutListener)
60
+ }
61
+
62
+ internal fun detachDimming() {
63
+ dimmingHost?.removeOnLayoutChangeListener(dimmingHostLayoutListener)
64
+ dimmingDrawable?.let { dimmingHost?.overlay?.remove(it) }
65
+ dimmingHost = null
66
+ dimmingDrawable = null
67
+ }
68
+
69
+ internal fun attachToBehavior(behavior: BottomSheetBehavior<*>) {
70
+ behavior.addBottomSheetCallback(
71
+ object : BottomSheetBehavior.BottomSheetCallback() {
72
+ override fun onStateChanged(
73
+ bottomSheet: View,
74
+ newState: Int,
75
+ ) = Unit
76
+
77
+ override fun onSlide(
78
+ bottomSheet: View,
79
+ slideOffset: Float,
80
+ ) {
81
+ // Prevent system updates from overriding alpha while running custom enter/exit animation.
82
+ // When initialDetentIndex is snapping to a high detent, BottomSheetBehavior fires onSlide
83
+ // events that conflict with our manual alpha animator, causing the backdrop to flash.
84
+ if (isTransitionAnimationRunning) {
85
+ return
86
+ }
87
+
88
+ val fraction = if (slideOffset >= 0) 1f else 1f + slideOffset
89
+ dimmingAlpha = fraction * maxAlpha
90
+ }
91
+ },
92
+ )
93
+ }
94
+
95
+ private fun resolveActivityDecorView(): View? = activityProvider()?.window?.decorView
96
+
97
+ companion object {
98
+ const val TAG = "FormSheetDimmingManager"
99
+
100
+ private const val MAX_DIMMING_ALPHA_FRACTION = 0.3f
101
+ private const val MAX_DRAWABLE_OVERLAY_ALPHA = 255
102
+ }
103
+ }
@@ -0,0 +1,22 @@
1
+ package com.swmansion.rnscreens.core.modals.formsheet.presentation
2
+
3
+ internal enum class FormSheetDismissalOrigin {
4
+ /**
5
+ * No dismissal request is pending. Completing a dismissal with this
6
+ * origin should report an error.
7
+ */
8
+ UNSPECIFIED,
9
+
10
+ /**
11
+ * The dismissal was requested from JS by setting `isOpen = false`.
12
+ * Emits `onDismiss`.
13
+ */
14
+ PROGRAMMATIC_JS,
15
+
16
+ /**
17
+ * The dismissal was initiated by the user (swiping the sheet down,
18
+ * triggering the native back button, or tapping the backdrop).
19
+ * Emits `onNativeDismiss`.
20
+ */
21
+ USER,
22
+ }
@@ -0,0 +1,173 @@
1
+ package com.swmansion.rnscreens.core.modals.formsheet.presentation
2
+
3
+ import android.content.Context
4
+ import android.util.Log
5
+ import android.view.ViewGroup
6
+ import android.widget.FrameLayout
7
+ import com.google.android.material.bottomsheet.BottomSheetBehavior
8
+ import com.swmansion.rnscreens.core.modals.formsheet.coordinator.FormSheetAppearanceCoordinator
9
+ import com.swmansion.rnscreens.core.modals.formsheet.coordinator.FormSheetBehaviorController
10
+ import com.swmansion.rnscreens.core.modals.formsheet.coordinator.FormSheetDimensionsCoordinator
11
+ import com.swmansion.rnscreens.core.modals.formsheet.coordinator.FormSheetKeyboardCoordinator
12
+ import com.swmansion.rnscreens.core.modals.formsheet.coordinator.FormSheetNativeDismissCoordinator
13
+ import com.swmansion.rnscreens.core.modals.formsheet.dialog.FormSheetContainer
14
+ import com.swmansion.rnscreens.core.modals.formsheet.dialog.FormSheetDialog
15
+ import com.swmansion.rnscreens.core.modals.formsheet.model.FormSheetConfig
16
+ import com.swmansion.rnscreens.core.modals.formsheet.model.FormSheetDetents
17
+
18
+ internal class FormSheetPresentation(
19
+ themedContext: Context,
20
+ private val container: FormSheetContainer,
21
+ private val callbacks: Callbacks,
22
+ ) {
23
+ internal interface Callbacks {
24
+ fun onDetentChanged(index: Int)
25
+
26
+ fun onNativeDismissAllowed()
27
+
28
+ fun onNativeDismissPrevented()
29
+ }
30
+
31
+ internal val dialog =
32
+ FormSheetDialog(themedContext).apply {
33
+ setContentView(container)
34
+ // Backdrop taps are handled by Material's `touch_outside` view, which calls `cancel()`,
35
+ // intercepted by FormSheetDialog.cancelRequestInterceptor, that's responsible for
36
+ // preventNativeDismiss handling.
37
+ setCanceledOnTouchOutside(true)
38
+ }
39
+
40
+ internal val bottomSheetView: FrameLayout? = dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet)
41
+
42
+ internal val sheetBehavior: BottomSheetBehavior<FrameLayout>?
43
+ get() = bottomSheetView?.let { BottomSheetBehavior.from(it) }
44
+
45
+ private val behaviorController =
46
+ bottomSheetView?.let {
47
+ FormSheetBehaviorController(it) { index -> callbacks.onDetentChanged(index) }
48
+ }
49
+
50
+ private val appearanceCoordinator =
51
+ FormSheetAppearanceCoordinator(
52
+ bottomSheetView = bottomSheetView,
53
+ )
54
+
55
+ private val dimensionsCoordinator =
56
+ FormSheetDimensionsCoordinator(
57
+ dialog = dialog,
58
+ container = container,
59
+ behaviorController = behaviorController,
60
+ )
61
+
62
+ private val keyboardCoordinator =
63
+ bottomSheetView?.let {
64
+ FormSheetKeyboardCoordinator(bottomSheetView = it)
65
+ }
66
+
67
+ private val nativeDismissCoordinator =
68
+ FormSheetNativeDismissCoordinator(
69
+ dialog = dialog,
70
+ behaviorController = behaviorController,
71
+ onDismissAllowed = callbacks::onNativeDismissAllowed,
72
+ onDismissPrevented = callbacks::onNativeDismissPrevented,
73
+ )
74
+
75
+ init {
76
+ nativeDismissCoordinator.setup()
77
+ appearanceCoordinator.setup()
78
+ dimensionsCoordinator.setup()
79
+ keyboardCoordinator?.setup()
80
+ behaviorController?.setup()
81
+ }
82
+
83
+ /**
84
+ * Enables tracking the keyboard animation. Expected to be on only while the sheet rests in the
85
+ * PRESENTED state - the enter / exit animators own `translationY` otherwise.
86
+ */
87
+ internal fun setKeyboardTrackingEnabled(enabled: Boolean) {
88
+ keyboardCoordinator?.isTrackingEnabled = enabled
89
+ }
90
+
91
+ internal fun onContentHeightChanged(height: Int) {
92
+ dimensionsCoordinator.onContentHeightChanged(height)
93
+ }
94
+
95
+ internal fun applyInitialConfig(
96
+ config: FormSheetConfig,
97
+ contentHeight: Int,
98
+ ) {
99
+ onContentHeightChanged(contentHeight)
100
+ dimensionsCoordinator.updateFormSheetDimensions(
101
+ resolveDetents(config.detents),
102
+ config.initialDetentIndex,
103
+ applyInitialDetent = true,
104
+ )
105
+ container.setGrabberVisible(config.prefersGrabberVisible)
106
+ appearanceCoordinator.updateCornerRadius(config.preferredCornerRadius)
107
+ appearanceCoordinator.updateBackgroundColor(config.nativeContainerBackgroundColor)
108
+ nativeDismissCoordinator.shouldPreventDismiss = config.shouldPreventNativeDismiss
109
+ }
110
+
111
+ internal fun applyConfigUpdate(
112
+ oldConfig: FormSheetConfig,
113
+ newConfig: FormSheetConfig,
114
+ ) {
115
+ if (oldConfig.detents != newConfig.detents) {
116
+ dimensionsCoordinator.updateFormSheetDimensions(
117
+ resolveDetents(newConfig.detents),
118
+ newConfig.initialDetentIndex,
119
+ )
120
+ }
121
+
122
+ if (oldConfig.prefersGrabberVisible != newConfig.prefersGrabberVisible) {
123
+ container.setGrabberVisible(newConfig.prefersGrabberVisible)
124
+ }
125
+
126
+ if (oldConfig.preferredCornerRadius != newConfig.preferredCornerRadius) {
127
+ appearanceCoordinator.updateCornerRadius(newConfig.preferredCornerRadius)
128
+ }
129
+
130
+ if (oldConfig.nativeContainerBackgroundColor != newConfig.nativeContainerBackgroundColor) {
131
+ appearanceCoordinator.updateBackgroundColor(newConfig.nativeContainerBackgroundColor)
132
+ }
133
+
134
+ if (oldConfig.shouldPreventNativeDismiss != newConfig.shouldPreventNativeDismiss) {
135
+ nativeDismissCoordinator.shouldPreventDismiss = newConfig.shouldPreventNativeDismiss
136
+ }
137
+ }
138
+
139
+ internal fun destroy() {
140
+ behaviorController?.destroy()
141
+ nativeDismissCoordinator.destroy()
142
+ dimensionsCoordinator.destroy()
143
+ keyboardCoordinator?.destroy()
144
+
145
+ dialog.setOnShowListener(null)
146
+ dialog.dismiss()
147
+
148
+ // The FormSheetContainer outlives the presentation - its lifecycle is managed by FormSheetDialogManager
149
+ // which is tied with the React's Host lifecycle.
150
+ (container.parent as? ViewGroup)?.removeView(container)
151
+ }
152
+
153
+ private fun resolveDetents(rawDetents: List<Double>): FormSheetDetents {
154
+ if (rawDetents.isEmpty()) {
155
+ return FormSheetDetents(listOf(LARGE_DETENT_FRACTION))
156
+ }
157
+
158
+ return try {
159
+ FormSheetDetents(rawDetents)
160
+ } catch (e: IllegalArgumentException) {
161
+ Log.e(
162
+ "[RNScreens]",
163
+ "Invalid FormSheet detents: $rawDetents. Falling back to large detent.",
164
+ e,
165
+ )
166
+ FormSheetDetents(listOf(LARGE_DETENT_FRACTION))
167
+ }
168
+ }
169
+
170
+ companion object {
171
+ private const val LARGE_DETENT_FRACTION = 1.0
172
+ }
173
+ }