react-native-screens 5.0.0-alpha.2 → 5.0.0-alpha.3
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.
- package/Package.swift +87 -0
- package/README.md +0 -7
- package/android/src/main/cpp/NativeProxy.cpp +30 -6
- package/android/src/main/cpp/NativeProxy.h +7 -1
- package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +8 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/container/ContainerItem.kt +13 -1
- package/android/src/main/java/com/swmansion/rnscreens/common/text/ReactTextAppearance.kt +62 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearance.kt +20 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearanceDefaults.kt +65 -0
- package/android/src/main/java/com/swmansion/rnscreens/helpers/PropIconResolver.kt +17 -23
- package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetBehaviorController.kt +49 -18
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetDimensionsCoordinator.kt +65 -40
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetKeyboardCoordinator.kt +101 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetNativeDismissCoordinator.kt +0 -6
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetAvailableHeightProvider.kt +44 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialog.kt +35 -3
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialogManager.kt +33 -106
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/interfaces/FormSheetDialogEventEmitter.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/model/FormSheetDetents.kt +61 -15
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetAnimatorFactory.kt +8 -9
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetDimmingManager.kt +115 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetDismissalOrigin.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentation.kt +173 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationManager.kt +141 -49
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationState.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetStackRegistry.kt +28 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/event/FormSheetDismissEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/host/FormSheetHostEventEmitter.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/host/FormSheetHostViewManager.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +369 -58
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderBackPressHandler.kt +11 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +143 -98
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +155 -23
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderContentScrimDrawable.kt +36 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderCollapsedTitleGravityMode.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +170 -167
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +385 -12
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +0 -4
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +32 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderDelegate.kt +0 -7
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +7 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +27 -280
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuController.kt +448 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuDelegate.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +28 -20
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuConfig.kt +3 -55
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuGroupMetadata.kt +1 -10
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuItemConfig.kt +1 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuModel.kt +180 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementOptions.kt +57 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueue.kt +23 -9
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +103 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +13 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHostViewManager.kt +14 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +20 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragmentDelegate.kt +12 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +2 -4
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/MenuHelpers.kt +5 -23
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +46 -25
- package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHostA11yCoordinator.kt +23 -2
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +17 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenFragment.kt +3 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/StyleUtils.kt +22 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_available_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_entire_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_available_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_entire_space.xml +8 -0
- package/cpp/legacy/RNSScreenRemovalListener.cpp +31 -1
- package/cpp/legacy/RNSScreenRemovalListener.h +18 -3
- package/ios/RNSEnums.h +2 -0
- package/ios/conversion/RNSConversions.h +7 -108
- package/ios/legacy/RNSFullWindowOverlay.mm +1 -1
- package/ios/legacy/RNSModalScreen.mm +1 -1
- package/ios/legacy/RNSScreen.mm +8 -19
- package/ios/legacy/RNSScreenStackHeaderConfig.mm +3 -1
- package/ios/legacy/RNSScreenStackHeaderSubview.mm +1 -1
- package/ios/legacy/RNSScreenWindowTraits.mm +5 -13
- package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.h +1 -3
- package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm +11 -22
- package/ios/modals/form-sheet/RNSFormSheetContentController.h +1 -1
- package/ios/modals/form-sheet/RNSFormSheetContentController.mm +7 -18
- package/ios/modals/form-sheet/RNSFormSheetHostComponentView.mm +4 -4
- package/ios/modals/form-sheet/RNSFormSheetHostShadowStateProxy.mm +2 -2
- package/ios/modals/form-sheet/RNSFormSheetUpdateFlags.h +3 -0
- package/ios/safe-area/RNSSafeAreaViewComponentView.mm +2 -2
- package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.mm +2 -3
- package/ios/split/RNSSplitAppearanceApplicator.h +4 -4
- package/ios/split/RNSSplitAppearanceApplicator.mm +53 -56
- package/ios/split/RNSSplitHostComponentEventEmitter.h +1 -0
- package/ios/split/RNSSplitHostComponentEventEmitter.mm +1 -1
- package/ios/split/RNSSplitHostComponentView.h +5 -15
- package/ios/split/RNSSplitHostComponentView.mm +55 -6
- package/ios/split/RNSSplitHostController.h +25 -6
- package/ios/split/RNSSplitHostController.mm +24 -92
- package/ios/split/RNSSplitHostProviders.h +67 -0
- package/ios/split/RNSSplitScreenComponentView.h +0 -39
- package/ios/split/RNSSplitScreenComponentView.mm +27 -10
- package/ios/split/RNSSplitScreenController.h +26 -3
- package/ios/split/RNSSplitScreenController.mm +13 -30
- package/ios/split/RNSSplitScreenShadowStateProxy.h +1 -40
- package/ios/split/RNSSplitScreenShadowStateProxy.mm +1 -26
- package/ios/split/conversion/RNSConversions-SplitView.h +56 -0
- package/ios/{conversion → split/conversion}/RNSConversions-SplitView.mm +4 -1
- package/ios/stack/conversion/RNSConversions-Stack.h +32 -0
- package/ios/stack/conversion/RNSConversions-Stack.mm +55 -0
- package/ios/stack/header/RNSStackHeaderAppearanceMapper.h +26 -0
- package/ios/stack/header/RNSStackHeaderAppearanceMapper.mm +88 -0
- package/ios/stack/header/RNSStackHeaderConfigComponentView.h +10 -1
- package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +67 -35
- package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +6 -0
- package/ios/stack/header/RNSStackHeaderConfigShadowStateProxy.mm +1 -1
- package/ios/stack/header/RNSStackHeaderIconResolver.mm +7 -0
- package/ios/stack/header/RNSStackHeaderItemComponentView.h +3 -1
- package/ios/stack/header/RNSStackHeaderItemComponentView.mm +15 -2
- package/ios/stack/header/RNSStackHeaderItemDataProviding.h +2 -0
- package/ios/stack/header/RNSStackHeaderItemShadowStateProxy.mm +1 -1
- package/ios/stack/header/RNSStackHeaderItemSpacerComponentView.mm +2 -1
- package/ios/stack/header/RNSStackHeaderMenuMapper.mm +4 -0
- package/ios/stack/host/RNSStackNavigationBar.h +25 -0
- package/ios/stack/host/RNSStackNavigationBar.mm +80 -0
- package/ios/stack/host/RNSStackNavigationBarCoordinator.h +8 -0
- package/ios/stack/host/RNSStackNavigationBarCoordinator.mm +11 -0
- package/ios/stack/host/RNSStackNavigationController.mm +13 -5
- package/ios/stack/host/RNSStackOperation.h +0 -2
- package/ios/stack/screen/RNSStackScreenComponentView.mm +9 -2
- package/ios/stack/screen/RNSStackScreenController.mm +12 -0
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +8 -0
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +98 -16
- package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +40 -9
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.h +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryEventEmitter.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryShadowStateProxy.mm +1 -1
- package/ios/tabs/conversion/RNSConversions-Tabs.h +78 -0
- package/ios/{conversion → tabs/conversion}/RNSConversions-Tabs.mm +8 -71
- package/ios/tabs/extensions/RNSTabsHostComponentView+RNSImageLoader.h +1 -1
- package/ios/tabs/host/RNSTabsHostComponentView.h +2 -0
- package/ios/tabs/host/RNSTabsHostComponentView.mm +10 -3
- package/ios/tabs/host/RNSTabsHostEventEmitter.mm +1 -1
- package/ios/tabs/screen/RNSTabsScreenComponentView.mm +20 -5
- package/ios/utils/RNSDefines.h +3 -0
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +34 -19
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +33 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/commonjs/components/stack/host/StackHost.js +9 -6
- package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
- package/lib/commonjs/components/stack/index.js.map +1 -1
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js +1 -0
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.android.js +35 -20
- package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js +34 -2
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/module/components/stack/host/StackHost.js +9 -6
- package/lib/module/components/stack/host/StackHost.js.map +1 -1
- package/lib/module/components/stack/index.js.map +1 -1
- package/lib/module/components/tabs/host/TabsHost.ios.js +1 -0
- package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +616 -21
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +226 -2
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +2 -2
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +2 -0
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.d.ts +1 -1
- package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.types.d.ts +24 -0
- package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/index.d.ts +2 -2
- package/lib/typescript/components/stack/index.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +16 -0
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.types.d.ts +3 -0
- package/lib/typescript/components/tabs/host/TabsHost.types.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +52 -0
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +25 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +2 -0
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +3 -1
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
- package/package.json +8 -7
- package/react-native.config.js +3 -0
- package/src/components/modals/form-sheet/FormSheet.types.ts +1 -1
- package/src/components/stack/header/StackHeaderConfig.android.tsx +48 -23
- package/src/components/stack/header/StackHeaderConfig.android.types.ts +637 -21
- package/src/components/stack/header/StackHeaderConfig.ios.tsx +45 -1
- package/src/components/stack/header/StackHeaderConfig.ios.types.ts +238 -2
- package/src/components/stack/header/StackHeaderConfig.types.ts +2 -2
- package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +2 -0
- package/src/components/stack/host/StackHost.tsx +4 -2
- package/src/components/stack/host/StackHost.types.ts +26 -0
- package/src/components/stack/index.ts +6 -1
- package/src/components/tabs/host/TabsHost.ios.tsx +1 -0
- package/src/components/tabs/host/TabsHost.ios.types.ts +16 -0
- package/src/components/tabs/host/TabsHost.types.ts +3 -0
- package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +78 -0
- package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +32 -0
- package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +2 -0
- package/src/fabric/stack/StackHostNativeComponent.ts +11 -2
- package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingView.kt +0 -83
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewManager.kt +0 -89
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewPointerEvents.kt +0 -18
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +0 -83
- package/ios/conversion/RNSConversions-Stack.h +0 -32
- package/ios/conversion/RNSConversions-Stack.mm +0 -41
- package/ios/conversion/always_false.h +0 -31
- /package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.h +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
package com.swmansion.rnscreens.modals.formsheet.native.model
|
|
2
2
|
|
|
3
|
+
import kotlin.math.roundToInt
|
|
4
|
+
|
|
3
5
|
internal class FormSheetDetents(
|
|
4
6
|
rawDetents: List<Double>,
|
|
5
7
|
) {
|
|
@@ -31,47 +33,83 @@ internal class FormSheetDetents(
|
|
|
31
33
|
|
|
32
34
|
private fun heightFractionAt(index: Int): Double = detents[index]
|
|
33
35
|
|
|
36
|
+
// Height of the sheet resting at the given detent, measured down to the bottom edge of the container.
|
|
34
37
|
private fun heightAt(
|
|
35
38
|
index: Int,
|
|
36
39
|
containerHeight: Int,
|
|
37
|
-
|
|
40
|
+
keyboardLift: Int,
|
|
41
|
+
): Int = ((heightFractionAt(index) * containerHeight).roundToInt() + keyboardLift).coerceAtMost(containerHeight)
|
|
38
42
|
|
|
39
|
-
|
|
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)
|
|
40
55
|
|
|
41
|
-
internal fun maxAllowedHeight(
|
|
56
|
+
internal fun maxAllowedHeight(
|
|
57
|
+
containerHeight: Int,
|
|
58
|
+
keyboardLift: Int = 0,
|
|
59
|
+
): Int = heightAt(count - 1, containerHeight, keyboardLift)
|
|
42
60
|
|
|
43
61
|
internal fun maxAllowedHeightForFitToContents(
|
|
44
62
|
containerHeight: Int,
|
|
45
63
|
contentHeight: Int,
|
|
46
64
|
bottomInset: Int,
|
|
65
|
+
keyboardLift: Int = 0,
|
|
47
66
|
): Int {
|
|
48
67
|
/*
|
|
49
|
-
* We add the `bottomInset` to the `contentHeight` so that the Material BottomSheet
|
|
50
|
-
* is laid out behind the system navigation bar. The sheet's container covers the insets,
|
|
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,
|
|
51
70
|
* while the RN content is strictly constrained to `contentHeight`.
|
|
52
71
|
*/
|
|
53
72
|
if (contentHeight <= 0) {
|
|
54
73
|
// Avoid collapsing the sheet before the React content has been laid out and measured.
|
|
55
74
|
return containerHeight
|
|
56
75
|
}
|
|
57
|
-
return (contentHeight + bottomInset).coerceAtMost(containerHeight)
|
|
76
|
+
return (contentHeight + bottomInset + keyboardLift).coerceAtMost(containerHeight)
|
|
58
77
|
}
|
|
59
78
|
|
|
60
|
-
|
|
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 {
|
|
61
91
|
check(count == MAX_DETENTS) { "[RNScreens] Exactly $MAX_DETENTS detents are required for halfExpandedRatio." }
|
|
62
|
-
|
|
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
|
|
63
97
|
}
|
|
64
98
|
|
|
65
99
|
internal fun expandedOffsetFromTop(
|
|
66
100
|
containerHeight: Int,
|
|
67
101
|
topInset: Int = 0,
|
|
102
|
+
keyboardLift: Int = 0,
|
|
68
103
|
): Int {
|
|
69
104
|
check(count == MAX_DETENTS) { "[RNScreens] Exactly $MAX_DETENTS detents are required for expandedOffsetFromTop." }
|
|
70
|
-
return (
|
|
105
|
+
return largestDetentTopOffset(containerHeight, keyboardLift) + topInset
|
|
71
106
|
}
|
|
72
107
|
|
|
73
108
|
// Distance from the top of the window to the top of the largest detent's surface.
|
|
74
|
-
private fun largestDetentTopOffset(
|
|
109
|
+
private fun largestDetentTopOffset(
|
|
110
|
+
containerHeight: Int,
|
|
111
|
+
keyboardLift: Int,
|
|
112
|
+
): Int = containerHeight - maxAllowedHeight(containerHeight, keyboardLift)
|
|
75
113
|
|
|
76
114
|
/**
|
|
77
115
|
* Material's BottomSheetDialog dynamically applies padding when its content overlaps
|
|
@@ -83,24 +121,32 @@ internal class FormSheetDetents(
|
|
|
83
121
|
topInset: Int,
|
|
84
122
|
bottomInset: Int,
|
|
85
123
|
contentHeight: Int = 0,
|
|
124
|
+
keyboardLift: Int = 0,
|
|
86
125
|
): Int {
|
|
126
|
+
val bottomPadding = bottomInset + keyboardLift
|
|
127
|
+
|
|
87
128
|
if (isFitToContents) {
|
|
88
129
|
// Until we have a measured content height, fall back to a safe-area height so Yoga can lay out.
|
|
89
130
|
if (contentHeight <= 0) {
|
|
90
|
-
return (containerHeight - topInset -
|
|
131
|
+
return (containerHeight - topInset - bottomPadding).coerceAtLeast(0)
|
|
91
132
|
}
|
|
92
|
-
|
|
133
|
+
// Content taller than the safe area is aligned with it.
|
|
134
|
+
return contentHeight.coerceAtMost((containerHeight - topInset - bottomPadding).coerceAtLeast(0))
|
|
93
135
|
}
|
|
94
136
|
|
|
95
|
-
// Bottom
|
|
137
|
+
// Bottom padding is always fully subtracted because the sheet is in its dedicated window and it's
|
|
96
138
|
// anchored to the bottom.
|
|
97
139
|
// Top inset is subtracted only by the amount the sheet actually overlaps it.
|
|
98
|
-
val topOverlap = (topInset - largestDetentTopOffset(containerHeight)).coerceAtLeast(0)
|
|
99
|
-
return (maxAllowedHeight(containerHeight) - topOverlap -
|
|
140
|
+
val topOverlap = (topInset - largestDetentTopOffset(containerHeight, keyboardLift)).coerceAtLeast(0)
|
|
141
|
+
return (maxAllowedHeight(containerHeight, keyboardLift) - topOverlap - bottomPadding).coerceAtLeast(0)
|
|
100
142
|
}
|
|
101
143
|
|
|
102
144
|
companion object {
|
|
103
145
|
const val MAX_DETENTS = 3
|
|
104
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
|
|
105
151
|
}
|
|
106
152
|
}
|
|
@@ -4,11 +4,9 @@ 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:
|
|
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.
|
|
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.
|
|
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
|
-
|
|
49
|
-
|
|
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.
|
|
60
|
+
dimmingManager.dimmingAlpha = animation.animatedValue as Float
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.modals.formsheet.native.presentation
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.ContextWrapper
|
|
6
|
+
import android.graphics.Color
|
|
7
|
+
import android.graphics.drawable.ColorDrawable
|
|
8
|
+
import android.util.Log
|
|
9
|
+
import android.view.View
|
|
10
|
+
import com.facebook.react.bridge.ReactContext
|
|
11
|
+
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
12
|
+
import kotlin.math.roundToInt
|
|
13
|
+
|
|
14
|
+
internal class FormSheetDimmingManager(
|
|
15
|
+
private val context: Context,
|
|
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? {
|
|
96
|
+
var current: Context? = context
|
|
97
|
+
while (current is ContextWrapper) {
|
|
98
|
+
if (current is Activity) {
|
|
99
|
+
return current.window?.decorView
|
|
100
|
+
}
|
|
101
|
+
if (current is ReactContext) {
|
|
102
|
+
return current.currentActivity?.window?.decorView
|
|
103
|
+
}
|
|
104
|
+
current = current.baseContext
|
|
105
|
+
}
|
|
106
|
+
return null
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
companion object {
|
|
110
|
+
const val TAG = "FormSheetDimmingManager"
|
|
111
|
+
|
|
112
|
+
private const val MAX_DIMMING_ALPHA_FRACTION = 0.3f
|
|
113
|
+
private const val MAX_DRAWABLE_OVERLAY_ALPHA = 255
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.modals.formsheet.native.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.modals.formsheet.native.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.modals.formsheet.native.coordinator.FormSheetAppearanceCoordinator
|
|
9
|
+
import com.swmansion.rnscreens.modals.formsheet.native.coordinator.FormSheetBehaviorController
|
|
10
|
+
import com.swmansion.rnscreens.modals.formsheet.native.coordinator.FormSheetDimensionsCoordinator
|
|
11
|
+
import com.swmansion.rnscreens.modals.formsheet.native.coordinator.FormSheetKeyboardCoordinator
|
|
12
|
+
import com.swmansion.rnscreens.modals.formsheet.native.coordinator.FormSheetNativeDismissCoordinator
|
|
13
|
+
import com.swmansion.rnscreens.modals.formsheet.native.core.FormSheetContainer
|
|
14
|
+
import com.swmansion.rnscreens.modals.formsheet.native.core.FormSheetDialog
|
|
15
|
+
import com.swmansion.rnscreens.modals.formsheet.native.model.FormSheetConfig
|
|
16
|
+
import com.swmansion.rnscreens.modals.formsheet.native.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
|
+
}
|