@amazon-devices/react-native-screens 2.0.1758683737
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/LICENSE +7 -0
- package/README.md +223 -0
- package/RNScreens.podspec +53 -0
- package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.bundle +33668 -0
- package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.map +1 -0
- package/SystemModules/amzn__react-native-screens.modules.txt +101 -0
- package/SystemModules/amzn__react-native-screens.private.modules.txt +244 -0
- package/SystemModules/keplerscript-system-bundle-config.json +7 -0
- package/THIRD_PARTY_NOTICES.txt +707 -0
- package/android/build.gradle +133 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +49 -0
- package/android/src/main/AndroidManifest.xml +5 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +77 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/FragmentHolder.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +21 -0
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +289 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +372 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +40 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +21 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +331 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +336 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +282 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +15 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +398 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +204 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +38 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +41 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +75 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +186 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +296 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +19 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +133 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +178 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +67 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +20 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +32 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +28 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +12 -0
- package/android/src/main/jni/CMakeLists.txt +72 -0
- package/android/src/main/jni/rnscreens.cpp +16 -0
- package/android/src/main/jni/rnscreens.h +28 -0
- package/android/src/main/res/base/anim/rns_default_enter_in.xml +18 -0
- package/android/src/main/res/base/anim/rns_default_enter_out.xml +19 -0
- package/android/src/main/res/base/anim/rns_default_exit_in.xml +17 -0
- package/android/src/main/res/base/anim/rns_default_exit_out.xml +18 -0
- package/android/src/main/res/base/anim/rns_fade_from_bottom.xml +14 -0
- package/android/src/main/res/base/anim/rns_fade_in.xml +7 -0
- package/android/src/main/res/base/anim/rns_fade_out.xml +7 -0
- package/android/src/main/res/base/anim/rns_fade_to_bottom.xml +15 -0
- package/android/src/main/res/base/anim/rns_no_animation_20.xml +6 -0
- package/android/src/main/res/base/anim/rns_no_animation_250.xml +7 -0
- package/android/src/main/res/base/anim/rns_no_animation_350.xml +6 -0
- package/android/src/main/res/base/anim/rns_no_animation_medium.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_bottom.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_left.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_right.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_bottom.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_left.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_right.xml +5 -0
- package/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml +6 -0
- package/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml +38 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +111 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +44 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +107 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +42 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerDelegate.java +31 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerInterface.java +17 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerInterface.java +16 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +41 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +9 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +30 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +14 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +45 -0
- package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h +11 -0
- package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm +14 -0
- package/ios/RNSConvert.h +36 -0
- package/ios/RNSConvert.mm +154 -0
- package/ios/RNSEnums.h +71 -0
- package/ios/RNSFullWindowOverlay.h +34 -0
- package/ios/RNSFullWindowOverlay.mm +241 -0
- package/ios/RNSScreen.h +144 -0
- package/ios/RNSScreen.mm +1599 -0
- package/ios/RNSScreenContainer.h +45 -0
- package/ios/RNSScreenContainer.mm +343 -0
- package/ios/RNSScreenNavigationContainer.h +16 -0
- package/ios/RNSScreenNavigationContainer.mm +66 -0
- package/ios/RNSScreenStack.h +37 -0
- package/ios/RNSScreenStack.mm +1111 -0
- package/ios/RNSScreenStackAnimator.h +8 -0
- package/ios/RNSScreenStackAnimator.mm +320 -0
- package/ios/RNSScreenStackHeaderConfig.h +74 -0
- package/ios/RNSScreenStackHeaderConfig.mm +967 -0
- package/ios/RNSScreenStackHeaderSubview.h +44 -0
- package/ios/RNSScreenStackHeaderSubview.mm +147 -0
- package/ios/RNSScreenWindowTraits.h +26 -0
- package/ios/RNSScreenWindowTraits.mm +266 -0
- package/ios/RNSSearchBar.h +43 -0
- package/ios/RNSSearchBar.mm +465 -0
- package/ios/RNScreens.xcodeproj/project.pbxproj +461 -0
- package/ios/UIViewController+RNScreens.h +9 -0
- package/ios/UIViewController+RNScreens.mm +78 -0
- package/ios/UIWindow+RNScreens.h +9 -0
- package/ios/UIWindow+RNScreens.mm +17 -0
- package/ios/events/RNSHeaderHeightChangeEvent.h +8 -0
- package/ios/events/RNSHeaderHeightChangeEvent.mm +44 -0
- package/ios/events/RNSScreenViewEvent.h +12 -0
- package/ios/events/RNSScreenViewEvent.mm +59 -0
- package/ios/utils/RNSUIBarButtonItem.h +5 -0
- package/ios/utils/RNSUIBarButtonItem.mm +22 -0
- package/kepler-compatibility.json +8 -0
- package/kepler-transformed-package-info.json +3 -0
- package/lib/commonjs/TransitionProgressContext.js +11 -0
- package/lib/commonjs/TransitionProgressContext.js.map +1 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +11 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +33 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js +70 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +11 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +31 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +12 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js +35 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js +19 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/commonjs/index.js +147 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/index.native.js +407 -0
- package/lib/commonjs/index.native.js.map +1 -0
- package/lib/commonjs/native-stack/index.js +49 -0
- package/lib/commonjs/native-stack/index.js.map +1 -0
- package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js +75 -0
- package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
- package/lib/commonjs/native-stack/types.js +6 -0
- package/lib/commonjs/native-stack/types.js.map +1 -0
- package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js +12 -0
- package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
- package/lib/commonjs/native-stack/utils/HeaderHeightContext.js +12 -0
- package/lib/commonjs/native-stack/utils/HeaderHeightContext.js.map +1 -0
- package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js +75 -0
- package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
- package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js +35 -0
- package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js +19 -0
- package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +54 -0
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useHeaderHeight.js +19 -0
- package/lib/commonjs/native-stack/utils/useHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/views/FontProcessor.js +21 -0
- package/lib/commonjs/native-stack/views/FontProcessor.js.map +1 -0
- package/lib/commonjs/native-stack/views/HeaderConfig.js +141 -0
- package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js +354 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js +12 -0
- package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +101 -0
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedScreen.js +22 -0
- package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +47 -0
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js +12 -0
- package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
- package/lib/commonjs/reanimated/index.js +28 -0
- package/lib/commonjs/reanimated/index.js.map +1 -0
- package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js +19 -0
- package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js.map +1 -0
- package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js +19 -0
- package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js.map +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/useTransitionProgress.js +19 -0
- package/lib/commonjs/useTransitionProgress.js.map +1 -0
- package/lib/commonjs/utils.js +21 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/TransitionProgressContext.js +3 -0
- package/lib/module/TransitionProgressContext.js.map +1 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +4 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js +25 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNativeComponent.js +63 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +4 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +23 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +7 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js +28 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/module/fabric/SearchBarNativeComponent.js +10 -0
- package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/module/index.js +67 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/index.native.js +410 -0
- package/lib/module/index.native.js.map +1 -0
- package/lib/module/native-stack/index.js +22 -0
- package/lib/module/native-stack/index.js.map +1 -0
- package/lib/module/native-stack/navigators/createNativeStackNavigator.js +72 -0
- package/lib/module/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
- package/lib/module/native-stack/types.js +2 -0
- package/lib/module/native-stack/types.js.map +1 -0
- package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js +4 -0
- package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
- package/lib/module/native-stack/utils/HeaderHeightContext.js +4 -0
- package/lib/module/native-stack/utils/HeaderHeightContext.js.map +1 -0
- package/lib/module/native-stack/utils/SafeAreaProviderCompat.js +68 -0
- package/lib/module/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
- package/lib/module/native-stack/utils/getDefaultHeaderHeight.js +29 -0
- package/lib/module/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js +10 -0
- package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/utils/useBackPressSubscription.js +47 -0
- package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/module/native-stack/utils/useHeaderHeight.js +10 -0
- package/lib/module/native-stack/utils/useHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/views/FontProcessor.js +13 -0
- package/lib/module/native-stack/views/FontProcessor.js.map +1 -0
- package/lib/module/native-stack/views/HeaderConfig.js +132 -0
- package/lib/module/native-stack/views/HeaderConfig.js.map +1 -0
- package/lib/module/native-stack/views/NativeStackView.js +355 -0
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -0
- package/lib/module/reanimated/ReanimatedHeaderHeightContext.js +5 -0
- package/lib/module/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js +97 -0
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/module/reanimated/ReanimatedScreen.js +17 -0
- package/lib/module/reanimated/ReanimatedScreen.js.map +1 -0
- package/lib/module/reanimated/ReanimatedScreenProvider.js +40 -0
- package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/module/reanimated/ReanimatedTransitionProgressContext.js +5 -0
- package/lib/module/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
- package/lib/module/reanimated/index.js +4 -0
- package/lib/module/reanimated/index.js.map +1 -0
- package/lib/module/reanimated/useReanimatedHeaderHeight.js +10 -0
- package/lib/module/reanimated/useReanimatedHeaderHeight.js.map +1 -0
- package/lib/module/reanimated/useReanimatedTransitionProgress.js +10 -0
- package/lib/module/reanimated/useReanimatedTransitionProgress.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/useTransitionProgress.js +10 -0
- package/lib/module/useTransitionProgress.js.map +1 -0
- package/lib/module/utils.js +14 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/TransitionProgressContext.d.ts +9 -0
- package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts +5 -0
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +66 -0
- package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +33 -0
- package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +10 -0
- package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +8 -0
- package/lib/typescript/fabric/SearchBarNativeComponent.d.ts +49 -0
- package/lib/typescript/index.d.ts +33 -0
- package/lib/typescript/index.native.d.ts +2 -0
- package/lib/typescript/native-stack/index.d.ts +19 -0
- package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts +6 -0
- package/lib/typescript/native-stack/types.d.ts +438 -0
- package/lib/typescript/native-stack/utils/AnimatedHeaderHeightContext.d.ts +4 -0
- package/lib/typescript/native-stack/utils/HeaderHeightContext.d.ts +3 -0
- package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts +11 -0
- package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +7 -0
- package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -0
- package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
- package/lib/typescript/native-stack/utils/useHeaderHeight.d.ts +1 -0
- package/lib/typescript/native-stack/views/FontProcessor.d.ts +1 -0
- package/lib/typescript/native-stack/views/HeaderConfig.d.ts +8 -0
- package/lib/typescript/native-stack/views/NativeStackView.d.ts +10 -0
- package/lib/typescript/reanimated/ReanimatedHeaderHeightContext.d.ts +4 -0
- package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
- package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -0
- package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
- package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts +9 -0
- package/lib/typescript/reanimated/index.d.ts +3 -0
- package/lib/typescript/reanimated/useReanimatedHeaderHeight.d.ts +3 -0
- package/lib/typescript/reanimated/useReanimatedTransitionProgress.d.ts +11 -0
- package/lib/typescript/types.d.ts +612 -0
- package/lib/typescript/useTransitionProgress.d.ts +5 -0
- package/lib/typescript/utils.d.ts +3 -0
- package/native-stack/README.md +814 -0
- package/native-stack/package.json +6 -0
- package/package.json +1 -0
- package/react-native.config.js +42 -0
- package/reanimated/package.json +6 -0
- package/src/TransitionProgressContext.tsx +12 -0
- package/src/fabric/FullWindowOverlayNativeComponent.ts +7 -0
- package/src/fabric/ScreenContainerNativeComponent.ts +28 -0
- package/src/fabric/ScreenNativeComponent.ts +158 -0
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +10 -0
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +61 -0
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +22 -0
- package/src/fabric/ScreenStackNativeComponent.ts +33 -0
- package/src/fabric/SearchBarNativeComponent.ts +79 -0
- package/src/index.native.tsx +599 -0
- package/src/index.tsx +119 -0
- package/src/native-stack/index.tsx +27 -0
- package/src/native-stack/navigators/createNativeStackNavigator.tsx +107 -0
- package/src/native-stack/types.tsx +486 -0
- package/src/native-stack/utils/AnimatedHeaderHeightContext.tsx +8 -0
- package/src/native-stack/utils/HeaderHeightContext.tsx +5 -0
- package/src/native-stack/utils/SafeAreaProviderCompat.tsx +78 -0
- package/src/native-stack/utils/getDefaultHeaderHeight.tsx +41 -0
- package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +15 -0
- package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
- package/src/native-stack/utils/useHeaderHeight.tsx +15 -0
- package/src/native-stack/views/FontProcessor.tsx +14 -0
- package/src/native-stack/views/HeaderConfig.tsx +187 -0
- package/src/native-stack/views/NativeStackView.tsx +466 -0
- package/src/reanimated/ReanimatedHeaderHeightContext.tsx +7 -0
- package/src/reanimated/ReanimatedNativeStackScreen.tsx +130 -0
- package/src/reanimated/ReanimatedScreen.tsx +25 -0
- package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
- package/src/reanimated/ReanimatedTransitionProgressContext.tsx +13 -0
- package/src/reanimated/index.tsx +3 -0
- package/src/reanimated/useReanimatedHeaderHeight.tsx +14 -0
- package/src/reanimated/useReanimatedTransitionProgress.tsx +14 -0
- package/src/types.tsx +699 -0
- package/src/useTransitionProgress.tsx +15 -0
- package/src/utils.ts +18 -0
- package/windows/README.md +25 -0
- package/windows/RNScreens/PropertySheet.props +16 -0
- package/windows/RNScreens/RNScreens.cpp +66 -0
- package/windows/RNScreens/RNScreens.def +3 -0
- package/windows/RNScreens/RNScreens.h +41 -0
- package/windows/RNScreens/RNScreens.idl +8 -0
- package/windows/RNScreens/RNScreens.vcxproj +187 -0
- package/windows/RNScreens/RNScreens.vcxproj.filters +52 -0
- package/windows/RNScreens/ReactPackageProvider.cpp +30 -0
- package/windows/RNScreens/ReactPackageProvider.h +17 -0
- package/windows/RNScreens/ReactPackageProvider.idl +9 -0
- package/windows/RNScreens/Screen.cpp +122 -0
- package/windows/RNScreens/Screen.h +64 -0
- package/windows/RNScreens/ScreenContainer.cpp +49 -0
- package/windows/RNScreens/ScreenContainer.h +23 -0
- package/windows/RNScreens/ScreenContainerViewManager.cpp +133 -0
- package/windows/RNScreens/ScreenContainerViewManager.h +78 -0
- package/windows/RNScreens/ScreenStack.cpp +65 -0
- package/windows/RNScreens/ScreenStack.h +23 -0
- package/windows/RNScreens/ScreenStackHeaderConfig.cpp +19 -0
- package/windows/RNScreens/ScreenStackHeaderConfig.h +14 -0
- package/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp +89 -0
- package/windows/RNScreens/ScreenStackHeaderConfigViewManager.h +62 -0
- package/windows/RNScreens/ScreenStackViewManager.cpp +132 -0
- package/windows/RNScreens/ScreenStackViewManager.h +78 -0
- package/windows/RNScreens/ScreenViewManager.cpp +154 -0
- package/windows/RNScreens/ScreenViewManager.h +78 -0
- package/windows/RNScreens/packages.config +4 -0
- package/windows/RNScreens/pch.cpp +1 -0
- package/windows/RNScreens/pch.h +9 -0
- package/windows/RNScreens62.sln +254 -0
- package/windows/RNScreens63.sln +225 -0
- package/windows/RNScreens65.sln +144 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import android.os.Bundle
|
|
7
|
+
import android.view.LayoutInflater
|
|
8
|
+
import android.view.Menu
|
|
9
|
+
import android.view.MenuInflater
|
|
10
|
+
import android.view.MenuItem
|
|
11
|
+
import android.view.View
|
|
12
|
+
import android.view.ViewGroup
|
|
13
|
+
import android.view.animation.Animation
|
|
14
|
+
import android.view.animation.AnimationSet
|
|
15
|
+
import android.view.animation.Transformation
|
|
16
|
+
import android.widget.LinearLayout
|
|
17
|
+
import androidx.appcompat.widget.Toolbar
|
|
18
|
+
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
19
|
+
import com.facebook.react.uimanager.PixelUtil
|
|
20
|
+
import com.google.android.material.appbar.AppBarLayout
|
|
21
|
+
import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior
|
|
22
|
+
import com.swmansion.rnscreens.utils.DeviceUtils
|
|
23
|
+
|
|
24
|
+
class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
|
|
25
|
+
private var mAppBarLayout: AppBarLayout? = null
|
|
26
|
+
private var mToolbar: Toolbar? = null
|
|
27
|
+
private var mShadowHidden = false
|
|
28
|
+
private var mIsTranslucent = false
|
|
29
|
+
|
|
30
|
+
private var mLastFocusedChild: View? = null
|
|
31
|
+
|
|
32
|
+
var searchView: CustomSearchView? = null
|
|
33
|
+
var onSearchViewCreate: ((searchView: CustomSearchView) -> Unit)? = null
|
|
34
|
+
|
|
35
|
+
@SuppressLint("ValidFragment")
|
|
36
|
+
constructor(screenView: Screen) : super(screenView)
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
throw IllegalStateException(
|
|
40
|
+
"ScreenStack fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity."
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override fun removeToolbar() {
|
|
45
|
+
mAppBarLayout?.let {
|
|
46
|
+
mToolbar?.let { toolbar ->
|
|
47
|
+
if (toolbar.parent === it) {
|
|
48
|
+
it.removeView(toolbar)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
mToolbar = null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override fun setToolbar(toolbar: Toolbar) {
|
|
56
|
+
mAppBarLayout?.addView(toolbar)
|
|
57
|
+
toolbar.layoutParams = AppBarLayout.LayoutParams(
|
|
58
|
+
AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT
|
|
59
|
+
).apply { scrollFlags = 0 }
|
|
60
|
+
mToolbar = toolbar
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override fun setToolbarShadowHidden(hidden: Boolean) {
|
|
64
|
+
if (mShadowHidden != hidden) {
|
|
65
|
+
mAppBarLayout?.targetElevation = if (hidden) 0f else PixelUtil.toPixelFromDIP(4f)
|
|
66
|
+
mShadowHidden = hidden
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
override fun setToolbarTranslucent(translucent: Boolean) {
|
|
71
|
+
if (mIsTranslucent != translucent) {
|
|
72
|
+
val params = screen.layoutParams
|
|
73
|
+
(params as CoordinatorLayout.LayoutParams).behavior =
|
|
74
|
+
if (translucent) null else ScrollingViewBehavior()
|
|
75
|
+
mIsTranslucent = translucent
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
override fun onContainerUpdate() {
|
|
80
|
+
screen.headerConfig?.onUpdate()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
override fun onViewAnimationEnd() {
|
|
84
|
+
super.onViewAnimationEnd()
|
|
85
|
+
notifyViewAppearTransitionEnd()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private fun notifyViewAppearTransitionEnd() {
|
|
89
|
+
val screenStack = view?.parent
|
|
90
|
+
if (screenStack is ScreenStack) {
|
|
91
|
+
screenStack.onViewAppearTransitionEnd()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
override fun onStart() {
|
|
96
|
+
mLastFocusedChild?.requestFocus()
|
|
97
|
+
super.onStart()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
override fun onCreateView(
|
|
101
|
+
inflater: LayoutInflater,
|
|
102
|
+
container: ViewGroup?,
|
|
103
|
+
savedInstanceState: Bundle?
|
|
104
|
+
): View? {
|
|
105
|
+
val view: ScreensCoordinatorLayout? =
|
|
106
|
+
context?.let { ScreensCoordinatorLayout(it, this) }
|
|
107
|
+
|
|
108
|
+
screen.layoutParams = CoordinatorLayout.LayoutParams(
|
|
109
|
+
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT
|
|
110
|
+
).apply { behavior = if (mIsTranslucent) null else ScrollingViewBehavior() }
|
|
111
|
+
|
|
112
|
+
view?.addView(recycleView(screen))
|
|
113
|
+
|
|
114
|
+
mAppBarLayout = context?.let { AppBarLayout(it) }?.apply {
|
|
115
|
+
// By default AppBarLayout will have a background color set but since we cover the whole layout
|
|
116
|
+
// with toolbar (that can be semi-transparent) the bar layout background color does not pay a
|
|
117
|
+
// role. On top of that it breaks screens animations when alfa offscreen compositing is off
|
|
118
|
+
// (which is the default)
|
|
119
|
+
setBackgroundColor(Color.TRANSPARENT)
|
|
120
|
+
layoutParams = AppBarLayout.LayoutParams(
|
|
121
|
+
AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
view?.addView(mAppBarLayout)
|
|
126
|
+
if (mShadowHidden) {
|
|
127
|
+
mAppBarLayout?.targetElevation = 0f
|
|
128
|
+
}
|
|
129
|
+
mToolbar?.let { mAppBarLayout?.addView(recycleView(it)) }
|
|
130
|
+
setHasOptionsMenu(true)
|
|
131
|
+
return view
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
override fun onStop() {
|
|
135
|
+
if (DeviceUtils.isPlatformAndroidTV(context))
|
|
136
|
+
mLastFocusedChild = findLastFocusedChild()
|
|
137
|
+
|
|
138
|
+
super.onStop()
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
override fun onPrepareOptionsMenu(menu: Menu) {
|
|
142
|
+
updateToolbarMenu(menu)
|
|
143
|
+
return super.onPrepareOptionsMenu(menu)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
|
147
|
+
updateToolbarMenu(menu)
|
|
148
|
+
return super.onCreateOptionsMenu(menu, inflater)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private fun shouldShowSearchBar(): Boolean {
|
|
152
|
+
val config = screen.headerConfig
|
|
153
|
+
val numberOfSubViews = config?.configSubviewsCount ?: 0
|
|
154
|
+
if (config != null && numberOfSubViews > 0) {
|
|
155
|
+
for (i in 0 until numberOfSubViews) {
|
|
156
|
+
val subView = config.getConfigSubview(i)
|
|
157
|
+
if (subView.type == ScreenStackHeaderSubview.Type.SEARCH_BAR) {
|
|
158
|
+
return true
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return false
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private fun updateToolbarMenu(menu: Menu) {
|
|
166
|
+
menu.clear()
|
|
167
|
+
if (shouldShowSearchBar()) {
|
|
168
|
+
val currentContext = context
|
|
169
|
+
if (searchView == null && currentContext != null) {
|
|
170
|
+
val newSearchView = CustomSearchView(currentContext, this)
|
|
171
|
+
searchView = newSearchView
|
|
172
|
+
onSearchViewCreate?.invoke(newSearchView)
|
|
173
|
+
}
|
|
174
|
+
menu.add("").apply {
|
|
175
|
+
setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
|
176
|
+
actionView = searchView
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private fun findLastFocusedChild(): View? {
|
|
182
|
+
var view: View? = screen
|
|
183
|
+
while (view != null) {
|
|
184
|
+
if (view.isFocused) return view
|
|
185
|
+
view = if (view is ViewGroup) view.focusedChild else null
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return null
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
override fun canNavigateBack(): Boolean {
|
|
192
|
+
val container: ScreenContainer? = screen.container
|
|
193
|
+
check(container is ScreenStack) { "ScreenStackFragment added into a non-stack container" }
|
|
194
|
+
return if (container.rootScreen == screen) {
|
|
195
|
+
// this screen is the root of the container, if it is nested we can check parent container
|
|
196
|
+
// if it is also a root or not
|
|
197
|
+
val parentFragment = parentFragment
|
|
198
|
+
if (parentFragment is ScreenStackFragment) {
|
|
199
|
+
parentFragment.canNavigateBack()
|
|
200
|
+
} else {
|
|
201
|
+
false
|
|
202
|
+
}
|
|
203
|
+
} else {
|
|
204
|
+
true
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
override fun dismiss() {
|
|
209
|
+
val container: ScreenContainer? = screen.container
|
|
210
|
+
check(container is ScreenStack) { "ScreenStackFragment added into a non-stack container" }
|
|
211
|
+
container.dismiss(this)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private class ScreensCoordinatorLayout(
|
|
215
|
+
context: Context,
|
|
216
|
+
private val mFragment: ScreenFragment
|
|
217
|
+
) : CoordinatorLayout(context) {
|
|
218
|
+
private val mAnimationListener: Animation.AnimationListener =
|
|
219
|
+
object : Animation.AnimationListener {
|
|
220
|
+
override fun onAnimationStart(animation: Animation) {
|
|
221
|
+
mFragment.onViewAnimationStart()
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
override fun onAnimationEnd(animation: Animation) {
|
|
225
|
+
mFragment.onViewAnimationEnd()
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
override fun onAnimationRepeat(animation: Animation) {}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
override fun startAnimation(animation: Animation) {
|
|
232
|
+
// For some reason View##onAnimationEnd doesn't get called for
|
|
233
|
+
// exit transitions so we explicitly attach animation listener.
|
|
234
|
+
// We also have some animations that are an AnimationSet, so we don't wrap them
|
|
235
|
+
// in another set since it causes some visual glitches when going forward.
|
|
236
|
+
// We also set the listener only when going forward, since when going back,
|
|
237
|
+
// there is already a listener for dismiss action added, which would be overridden
|
|
238
|
+
// and also this is not necessary when going back since the lifecycle methods
|
|
239
|
+
// are correctly dispatched then.
|
|
240
|
+
// We also add fakeAnimation to the set of animations, which sends the progress of animation
|
|
241
|
+
val fakeAnimation = ScreensAnimation(mFragment).apply { duration = animation.duration }
|
|
242
|
+
|
|
243
|
+
if (animation is AnimationSet && !mFragment.isRemoving) {
|
|
244
|
+
animation.apply {
|
|
245
|
+
addAnimation(fakeAnimation)
|
|
246
|
+
setAnimationListener(mAnimationListener)
|
|
247
|
+
}.also {
|
|
248
|
+
super.startAnimation(it)
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
AnimationSet(true).apply {
|
|
252
|
+
addAnimation(animation)
|
|
253
|
+
addAnimation(fakeAnimation)
|
|
254
|
+
setAnimationListener(mAnimationListener)
|
|
255
|
+
}.also {
|
|
256
|
+
super.startAnimation(it)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* This method implements a workaround for RN's autoFocus functionality. Because of the way
|
|
263
|
+
* autoFocus is implemented it dismisses soft keyboard in fragment transition
|
|
264
|
+
* due to change of visibility of the view at the start of the transition. Here we override the
|
|
265
|
+
* call to `clearFocus` when the visibility of view is `INVISIBLE` since `clearFocus` triggers the
|
|
266
|
+
* hiding of the keyboard in `ReactEditText.java`.
|
|
267
|
+
*/
|
|
268
|
+
override fun clearFocus() {
|
|
269
|
+
if (visibility != INVISIBLE) {
|
|
270
|
+
super.clearFocus()
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private class ScreensAnimation(private val mFragment: ScreenFragment) : Animation() {
|
|
276
|
+
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
|
277
|
+
super.applyTransformation(interpolatedTime, t)
|
|
278
|
+
// interpolated time should be the progress of the current transition
|
|
279
|
+
mFragment.dispatchTransitionProgressEvent(interpolatedTime, !mFragment.isResumed)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import androidx.appcompat.widget.Toolbar
|
|
4
|
+
|
|
5
|
+
interface ScreenStackFragmentWrapper : ScreenFragmentWrapper {
|
|
6
|
+
// Toolbar management
|
|
7
|
+
fun removeToolbar()
|
|
8
|
+
fun setToolbar(toolbar: Toolbar)
|
|
9
|
+
fun setToolbarShadowHidden(hidden: Boolean)
|
|
10
|
+
fun setToolbarTranslucent(translucent: Boolean)
|
|
11
|
+
|
|
12
|
+
// Navigation
|
|
13
|
+
fun canNavigateBack(): Boolean
|
|
14
|
+
fun dismiss()
|
|
15
|
+
}
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.PorterDuff
|
|
5
|
+
import android.os.Build
|
|
6
|
+
import android.text.TextUtils
|
|
7
|
+
import android.util.TypedValue
|
|
8
|
+
import android.view.Gravity
|
|
9
|
+
import android.view.View.OnClickListener
|
|
10
|
+
import android.view.ViewGroup
|
|
11
|
+
import android.widget.ImageView
|
|
12
|
+
import android.widget.TextView
|
|
13
|
+
import androidx.appcompat.app.AppCompatActivity
|
|
14
|
+
import androidx.appcompat.widget.Toolbar
|
|
15
|
+
import androidx.fragment.app.Fragment
|
|
16
|
+
import com.facebook.react.ReactApplication
|
|
17
|
+
import com.facebook.react.bridge.JSApplicationIllegalArgumentException
|
|
18
|
+
import com.facebook.react.bridge.ReactContext
|
|
19
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
20
|
+
import com.facebook.react.views.text.ReactTypefaceUtils
|
|
21
|
+
import com.swmansion.rnscreens.events.HeaderAttachedEvent
|
|
22
|
+
import com.swmansion.rnscreens.events.HeaderDetachedEvent
|
|
23
|
+
|
|
24
|
+
class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) {
|
|
25
|
+
private val mConfigSubviews = ArrayList<ScreenStackHeaderSubview>(3)
|
|
26
|
+
val toolbar: CustomToolbar
|
|
27
|
+
private var headerTopInset: Int? = null
|
|
28
|
+
private var mTitle: String? = null
|
|
29
|
+
private var mTitleColor = 0
|
|
30
|
+
private var mTitleFontFamily: String? = null
|
|
31
|
+
private var mDirection: String? = null
|
|
32
|
+
private var mTitleFontSize = 0f
|
|
33
|
+
private var mTitleFontWeight = 0
|
|
34
|
+
private var mBackgroundColor: Int? = null
|
|
35
|
+
private var mIsHidden = false
|
|
36
|
+
private var mIsBackButtonHidden = false
|
|
37
|
+
private var mIsShadowHidden = false
|
|
38
|
+
private var mDestroyed = false
|
|
39
|
+
private var mBackButtonInCustomView = false
|
|
40
|
+
private var mIsTopInsetEnabled = true
|
|
41
|
+
private var mIsTranslucent = false
|
|
42
|
+
private var mTintColor = 0
|
|
43
|
+
private var mIsAttachedToWindow = false
|
|
44
|
+
private val mDefaultStartInset: Int
|
|
45
|
+
private val mDefaultStartInsetWithNavigation: Int
|
|
46
|
+
private val mBackClickListener = OnClickListener {
|
|
47
|
+
screenFragment?.let {
|
|
48
|
+
val stack = screenStack
|
|
49
|
+
if (stack != null && stack.rootScreen == it.screen) {
|
|
50
|
+
val parentFragment = it.parentFragment
|
|
51
|
+
if (parentFragment is ScreenStackFragment) {
|
|
52
|
+
if (parentFragment.screen.nativeBackButtonDismissalEnabled) {
|
|
53
|
+
parentFragment.dismiss()
|
|
54
|
+
} else {
|
|
55
|
+
parentFragment.dispatchHeaderBackButtonClickedEvent()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
if (it.screen.nativeBackButtonDismissalEnabled) {
|
|
60
|
+
it.dismiss()
|
|
61
|
+
} else {
|
|
62
|
+
it.dispatchHeaderBackButtonClickedEvent()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
|
69
|
+
// no-op
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fun destroy() {
|
|
73
|
+
mDestroyed = true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
override fun onAttachedToWindow() {
|
|
77
|
+
super.onAttachedToWindow()
|
|
78
|
+
mIsAttachedToWindow = true
|
|
79
|
+
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
80
|
+
UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
|
|
81
|
+
?.dispatchEvent(HeaderAttachedEvent(surfaceId, id))
|
|
82
|
+
// we want to save the top inset before the status bar can be hidden, which would resolve in
|
|
83
|
+
// inset being 0
|
|
84
|
+
if (headerTopInset == null) {
|
|
85
|
+
headerTopInset = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
|
86
|
+
rootWindowInsets.systemWindowInsetTop
|
|
87
|
+
else
|
|
88
|
+
// Hacky fallback for old android. Before Marshmallow, the status bar height was always 25
|
|
89
|
+
(25 * resources.displayMetrics.density).toInt()
|
|
90
|
+
}
|
|
91
|
+
onUpdate()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
override fun onDetachedFromWindow() {
|
|
95
|
+
super.onDetachedFromWindow()
|
|
96
|
+
mIsAttachedToWindow = false
|
|
97
|
+
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
98
|
+
UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
|
|
99
|
+
?.dispatchEvent(HeaderDetachedEvent(surfaceId, id))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private val screen: Screen?
|
|
103
|
+
get() = parent as? Screen
|
|
104
|
+
private val screenStack: ScreenStack?
|
|
105
|
+
get() = screen?.container as? ScreenStack
|
|
106
|
+
val screenFragment: ScreenStackFragment?
|
|
107
|
+
get() {
|
|
108
|
+
val screen = parent
|
|
109
|
+
if (screen is Screen) {
|
|
110
|
+
val fragment: Fragment? = screen.fragment
|
|
111
|
+
if (fragment is ScreenStackFragment) {
|
|
112
|
+
return fragment
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
fun onUpdate() {
|
|
119
|
+
val stack = screenStack
|
|
120
|
+
val isTop = stack == null || stack.topScreen == parent
|
|
121
|
+
|
|
122
|
+
if (!mIsAttachedToWindow || !isTop || mDestroyed) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
val activity = screenFragment?.activity as AppCompatActivity? ?: return
|
|
127
|
+
if (mDirection != null) {
|
|
128
|
+
if (mDirection == "rtl") {
|
|
129
|
+
toolbar.layoutDirection = LAYOUT_DIRECTION_RTL
|
|
130
|
+
} else if (mDirection == "ltr") {
|
|
131
|
+
toolbar.layoutDirection = LAYOUT_DIRECTION_LTR
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// orientation and status bar management
|
|
136
|
+
screen?.let {
|
|
137
|
+
// we set the traits here too, not only when the prop for Screen is passed
|
|
138
|
+
// because sometimes we don't have the Fragment and Activity available then yet, e.g. on the
|
|
139
|
+
// first setting of props. Similar thing is done for Screens of ScreenContainers, but in
|
|
140
|
+
// `onContainerUpdate` of their Fragment
|
|
141
|
+
val reactContext = if (context is ReactContext) {
|
|
142
|
+
context as ReactContext
|
|
143
|
+
} else {
|
|
144
|
+
it.fragmentWrapper?.tryGetContext()
|
|
145
|
+
}
|
|
146
|
+
ScreenWindowTraits.trySetWindowTraits(it, activity, reactContext)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (mIsHidden) {
|
|
150
|
+
if (toolbar.parent != null) {
|
|
151
|
+
screenFragment?.removeToolbar()
|
|
152
|
+
}
|
|
153
|
+
return
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (toolbar.parent == null) {
|
|
157
|
+
screenFragment?.setToolbar(toolbar)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (mIsTopInsetEnabled) {
|
|
161
|
+
headerTopInset.let {
|
|
162
|
+
toolbar.setPadding(0, it ?: 0, 0, 0)
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
if (toolbar.paddingTop > 0) {
|
|
166
|
+
toolbar.setPadding(0, 0, 0, 0)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
activity.setSupportActionBar(toolbar)
|
|
171
|
+
// non-null toolbar is set in the line above and it is used here
|
|
172
|
+
val actionBar = requireNotNull(activity.supportActionBar)
|
|
173
|
+
|
|
174
|
+
// Reset toolbar insets. By default we set symmetric inset for start and end to match iOS
|
|
175
|
+
// implementation where both right and left icons are offset from the edge by default. We also
|
|
176
|
+
// reset startWithNavigation inset which corresponds to the distance between navigation icon and
|
|
177
|
+
// title. If title isn't set we clear that value few lines below to give more space to custom
|
|
178
|
+
// center-mounted views.
|
|
179
|
+
toolbar.contentInsetStartWithNavigation = mDefaultStartInsetWithNavigation
|
|
180
|
+
toolbar.setContentInsetsRelative(mDefaultStartInset, mDefaultStartInset)
|
|
181
|
+
|
|
182
|
+
// hide back button
|
|
183
|
+
actionBar.setDisplayHomeAsUpEnabled(
|
|
184
|
+
screenFragment?.canNavigateBack() == true && !mIsBackButtonHidden
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
// when setSupportActionBar is called a toolbar wrapper gets initialized that overwrites
|
|
188
|
+
// navigation click listener. The default behavior set in the wrapper is to call into
|
|
189
|
+
// menu options handlers, but we prefer the back handling logic to stay here instead.
|
|
190
|
+
toolbar.setNavigationOnClickListener(mBackClickListener)
|
|
191
|
+
|
|
192
|
+
// shadow
|
|
193
|
+
screenFragment?.setToolbarShadowHidden(mIsShadowHidden)
|
|
194
|
+
|
|
195
|
+
// translucent
|
|
196
|
+
screenFragment?.setToolbarTranslucent(mIsTranslucent)
|
|
197
|
+
|
|
198
|
+
// title
|
|
199
|
+
actionBar.title = mTitle
|
|
200
|
+
if (TextUtils.isEmpty(mTitle)) {
|
|
201
|
+
// if title is empty we set start navigation inset to 0 to give more space to custom rendered
|
|
202
|
+
// views. When it is set to default it'd take up additional distance from the back button
|
|
203
|
+
// which would impact the position of custom header views rendered at the center.
|
|
204
|
+
toolbar.contentInsetStartWithNavigation = 0
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
val titleTextView = titleTextView
|
|
208
|
+
if (mTitleColor != 0) {
|
|
209
|
+
toolbar.setTitleTextColor(mTitleColor)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (titleTextView != null) {
|
|
213
|
+
if (mTitleFontFamily != null || mTitleFontWeight > 0) {
|
|
214
|
+
val titleTypeface = ReactTypefaceUtils.applyStyles(
|
|
215
|
+
null, 0, mTitleFontWeight, mTitleFontFamily, context.assets
|
|
216
|
+
)
|
|
217
|
+
titleTextView.typeface = titleTypeface
|
|
218
|
+
}
|
|
219
|
+
if (mTitleFontSize > 0) {
|
|
220
|
+
titleTextView.textSize = mTitleFontSize
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// background
|
|
225
|
+
mBackgroundColor?.let { toolbar.setBackgroundColor(it) }
|
|
226
|
+
|
|
227
|
+
// color
|
|
228
|
+
if (mTintColor != 0) {
|
|
229
|
+
toolbar.navigationIcon?.setColorFilter(mTintColor, PorterDuff.Mode.SRC_ATOP)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// subviews
|
|
233
|
+
for (i in toolbar.childCount - 1 downTo 0) {
|
|
234
|
+
if (toolbar.getChildAt(i) is ScreenStackHeaderSubview) {
|
|
235
|
+
toolbar.removeViewAt(i)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
var i = 0
|
|
240
|
+
val size = mConfigSubviews.size
|
|
241
|
+
while (i < size) {
|
|
242
|
+
val view = mConfigSubviews[i]
|
|
243
|
+
val type = view.type
|
|
244
|
+
if (type === ScreenStackHeaderSubview.Type.BACK) {
|
|
245
|
+
// we special case BACK button header config type as we don't add it as a view into toolbar
|
|
246
|
+
// but instead just copy the drawable from imageview that's added as a first child to it.
|
|
247
|
+
val firstChild = view.getChildAt(0) as? ImageView
|
|
248
|
+
?: throw JSApplicationIllegalArgumentException(
|
|
249
|
+
"Back button header config view should have Image as first child"
|
|
250
|
+
)
|
|
251
|
+
actionBar.setHomeAsUpIndicator(firstChild.drawable)
|
|
252
|
+
i++
|
|
253
|
+
continue
|
|
254
|
+
}
|
|
255
|
+
val params = Toolbar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
|
|
256
|
+
when (type) {
|
|
257
|
+
ScreenStackHeaderSubview.Type.LEFT -> {
|
|
258
|
+
// when there is a left item we need to disable navigation icon by default
|
|
259
|
+
// we also hide title as there is no other way to display left side items
|
|
260
|
+
if (!mBackButtonInCustomView) {
|
|
261
|
+
toolbar.navigationIcon = null
|
|
262
|
+
}
|
|
263
|
+
toolbar.title = null
|
|
264
|
+
params.gravity = Gravity.START
|
|
265
|
+
}
|
|
266
|
+
ScreenStackHeaderSubview.Type.RIGHT -> params.gravity = Gravity.END
|
|
267
|
+
ScreenStackHeaderSubview.Type.CENTER -> {
|
|
268
|
+
params.width = LayoutParams.MATCH_PARENT
|
|
269
|
+
params.gravity = Gravity.CENTER_HORIZONTAL
|
|
270
|
+
toolbar.title = null
|
|
271
|
+
}
|
|
272
|
+
else -> {}
|
|
273
|
+
}
|
|
274
|
+
view.layoutParams = params
|
|
275
|
+
toolbar.addView(view)
|
|
276
|
+
i++
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private fun maybeUpdate() {
|
|
281
|
+
if (parent != null && !mDestroyed) {
|
|
282
|
+
onUpdate()
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
fun getConfigSubview(index: Int): ScreenStackHeaderSubview = mConfigSubviews[index]
|
|
287
|
+
|
|
288
|
+
val configSubviewsCount: Int
|
|
289
|
+
get() = mConfigSubviews.size
|
|
290
|
+
|
|
291
|
+
fun removeConfigSubview(index: Int) {
|
|
292
|
+
mConfigSubviews.removeAt(index)
|
|
293
|
+
maybeUpdate()
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
fun removeAllConfigSubviews() {
|
|
297
|
+
mConfigSubviews.clear()
|
|
298
|
+
maybeUpdate()
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
fun addConfigSubview(child: ScreenStackHeaderSubview, index: Int) {
|
|
302
|
+
mConfigSubviews.add(index, child)
|
|
303
|
+
maybeUpdate()
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
private val titleTextView: TextView?
|
|
307
|
+
get() {
|
|
308
|
+
for (i in 0 until toolbar.childCount) {
|
|
309
|
+
val view = toolbar.getChildAt(i)
|
|
310
|
+
if (view is TextView) {
|
|
311
|
+
if (view.text == toolbar.title) {
|
|
312
|
+
return view
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return null
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
fun setTitle(title: String?) {
|
|
320
|
+
mTitle = title
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
fun setTitleFontFamily(titleFontFamily: String?) {
|
|
324
|
+
mTitleFontFamily = titleFontFamily
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
fun setTitleFontWeight(fontWeightString: String?) {
|
|
328
|
+
mTitleFontWeight = ReactTypefaceUtils.parseFontWeight(fontWeightString)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
fun setTitleFontSize(titleFontSize: Float) {
|
|
332
|
+
mTitleFontSize = titleFontSize
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
fun setTitleColor(color: Int) {
|
|
336
|
+
mTitleColor = color
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
fun setTintColor(color: Int) {
|
|
340
|
+
mTintColor = color
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
fun setTopInsetEnabled(topInsetEnabled: Boolean) {
|
|
344
|
+
mIsTopInsetEnabled = topInsetEnabled
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
fun setBackgroundColor(color: Int?) {
|
|
348
|
+
mBackgroundColor = color
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
fun setHideShadow(hideShadow: Boolean) {
|
|
352
|
+
mIsShadowHidden = hideShadow
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
fun setHideBackButton(hideBackButton: Boolean) {
|
|
356
|
+
mIsBackButtonHidden = hideBackButton
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
fun setHidden(hidden: Boolean) {
|
|
360
|
+
mIsHidden = hidden
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
fun setTranslucent(translucent: Boolean) {
|
|
364
|
+
mIsTranslucent = translucent
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
fun setBackButtonInCustomView(backButtonInCustomView: Boolean) {
|
|
368
|
+
mBackButtonInCustomView = backButtonInCustomView
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
fun setDirection(direction: String?) {
|
|
372
|
+
mDirection = direction
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private class DebugMenuToolbar(context: Context, config: ScreenStackHeaderConfig) : CustomToolbar(context, config) {
|
|
376
|
+
override fun showOverflowMenu(): Boolean {
|
|
377
|
+
(context.applicationContext as ReactApplication)
|
|
378
|
+
.reactNativeHost
|
|
379
|
+
.reactInstanceManager
|
|
380
|
+
.showDevOptionsDialog()
|
|
381
|
+
return true
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
init {
|
|
386
|
+
visibility = GONE
|
|
387
|
+
toolbar = if (BuildConfig.DEBUG) DebugMenuToolbar(context, this) else CustomToolbar(context, this)
|
|
388
|
+
mDefaultStartInset = toolbar.contentInsetStart
|
|
389
|
+
mDefaultStartInsetWithNavigation = toolbar.contentInsetStartWithNavigation
|
|
390
|
+
|
|
391
|
+
// set primary color as background by default
|
|
392
|
+
val tv = TypedValue()
|
|
393
|
+
if (context.theme.resolveAttribute(R.attr.colorPrimary, tv, true)) {
|
|
394
|
+
toolbar.setBackgroundColor(tv.data)
|
|
395
|
+
}
|
|
396
|
+
toolbar.clipChildren = false
|
|
397
|
+
}
|
|
398
|
+
}
|