react-native-screens 3.35.0-rc.1 → 4.0.0-beta.1
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/README.md +1 -1
- package/android/build.gradle +28 -8
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +40 -1
- package/android/src/main/java/com/swmansion/rnscreens/InsetsObserverProxy.kt +67 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +119 -38
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContentWrapper.kt +38 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContentWrapperManager.kt +25 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFooter.kt +287 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFooterManager.kt +25 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +11 -19
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenModalFragment.kt +281 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +71 -22
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +403 -41
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +97 -12
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +40 -29
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogRootView.kt +104 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetDialogScreen.kt +26 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingFragment.kt +488 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingView.kt +66 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/GestureTransparentViewGroup.kt +24 -0
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt +127 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +3 -3
- package/android/src/main/java/com/swmansion/rnscreens/events/SheetDetentChangedEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/rnscreens/ext/NumericExt.kt +12 -0
- package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +32 -0
- package/android/src/main/res/base/anim/rns_ios_from_left_background_close.xml +5 -0
- package/android/src/main/res/base/anim/{rns_slide_out_to_left_ios.xml → rns_ios_from_left_background_open.xml} +1 -1
- package/android/src/main/res/base/anim/rns_ios_from_left_foreground_close.xml +6 -0
- package/android/src/main/res/base/anim/rns_ios_from_left_foreground_open.xml +6 -0
- package/android/src/main/res/base/anim/rns_ios_from_right_background_open.xml +5 -0
- package/android/src/main/res/base/drawable/rns_rounder_top_corners_shape.xml +8 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContentWrapperManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContentWrapperManagerInterface.java +16 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenFooterManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenFooterManagerInterface.java +16 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +9 -2
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +5 -2
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +1 -1
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +5 -99
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +101 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +2 -0
- package/ios/RNSConvert.h +5 -3
- package/ios/RNSConvert.mm +18 -21
- package/ios/RNSFullWindowOverlay.mm +6 -0
- package/ios/RNSModalScreen.mm +7 -0
- package/ios/RNSScreen.h +3 -2
- package/ios/RNSScreen.mm +442 -49
- package/ios/RNSScreenContainer.mm +6 -0
- package/ios/RNSScreenContentWrapper.h +44 -0
- package/ios/RNSScreenContentWrapper.mm +67 -0
- package/ios/RNSScreenFooter.h +30 -0
- package/ios/RNSScreenFooter.mm +143 -0
- package/ios/RNSScreenNavigationContainer.mm +7 -0
- package/ios/RNSScreenStack.mm +7 -7
- package/ios/RNSScreenStackHeaderConfig.mm +10 -0
- package/ios/RNSScreenStackHeaderSubview.mm +6 -3
- package/ios/RNSSearchBar.mm +7 -0
- package/lib/commonjs/TransitionProgressContext.js +1 -0
- package/lib/commonjs/TransitionProgressContext.js.map +1 -1
- package/lib/commonjs/components/Screen.js +63 -4
- package/lib/commonjs/components/Screen.js.map +1 -1
- package/lib/commonjs/components/Screen.web.js +2 -0
- package/lib/commonjs/components/Screen.web.js.map +1 -1
- package/lib/commonjs/components/ScreenContainer.js +1 -0
- package/lib/commonjs/components/ScreenContainer.js.map +1 -1
- package/lib/commonjs/components/ScreenContentWrapper.js +19 -0
- package/lib/commonjs/components/ScreenContentWrapper.js.map +1 -0
- package/lib/commonjs/components/ScreenFooter.js +23 -0
- package/lib/commonjs/components/ScreenFooter.js.map +1 -0
- package/lib/commonjs/components/ScreenStack.js +1 -0
- package/lib/commonjs/components/ScreenStack.js.map +1 -1
- package/lib/commonjs/components/ScreenStackHeaderConfig.js +1 -0
- package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/commonjs/components/SearchBar.js +1 -0
- package/lib/commonjs/components/SearchBar.js.map +1 -1
- package/lib/commonjs/core.js +1 -0
- package/lib/commonjs/core.js.map +1 -1
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +1 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/NativeScreensModule.js +2 -1
- package/lib/commonjs/fabric/NativeScreensModule.js.map +1 -1
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenContentWrapperNativeComponent.js +10 -0
- package/lib/commonjs/fabric/ScreenContentWrapperNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenFooterNativeComponent.js +10 -0
- package/lib/commonjs/fabric/ScreenFooterNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js +1 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/SearchBarNativeComponent.js +2 -2
- package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -1
- package/lib/commonjs/index.js +30 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/native-stack/contexts/GHContext.js +1 -0
- package/lib/commonjs/native-stack/contexts/GHContext.js.map +1 -1
- package/lib/commonjs/native-stack/views/FooterComponent.js +18 -0
- package/lib/commonjs/native-stack/views/FooterComponent.js.map +1 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js +59 -14
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/TransitionProgressContext.js +2 -0
- package/lib/module/TransitionProgressContext.js.map +1 -1
- package/lib/module/components/Screen.js +64 -4
- package/lib/module/components/Screen.js.map +1 -1
- package/lib/module/components/Screen.web.js +3 -0
- package/lib/module/components/Screen.web.js.map +1 -1
- package/lib/module/components/ScreenContainer.js +2 -0
- package/lib/module/components/ScreenContainer.js.map +1 -1
- package/lib/module/components/ScreenContentWrapper.js +12 -0
- package/lib/module/components/ScreenContentWrapper.js.map +1 -0
- package/lib/module/components/ScreenFooter.js +17 -0
- package/lib/module/components/ScreenFooter.js.map +1 -0
- package/lib/module/components/ScreenStack.js +2 -0
- package/lib/module/components/ScreenStack.js.map +1 -1
- package/lib/module/components/ScreenStackHeaderConfig.js +2 -0
- package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
- package/lib/module/components/SearchBar.js +2 -0
- package/lib/module/components/SearchBar.js.map +1 -1
- package/lib/module/core.js +2 -0
- package/lib/module/core.js.map +1 -1
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +2 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -1
- package/lib/module/fabric/ModalScreenNativeComponent.js +2 -0
- package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/NativeScreensModule.js +2 -1
- package/lib/module/fabric/NativeScreensModule.js.map +1 -1
- package/lib/module/fabric/ScreenContainerNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenContentWrapperNativeComponent.js +3 -0
- package/lib/module/fabric/ScreenContentWrapperNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenFooterNativeComponent.js +3 -0
- package/lib/module/fabric/ScreenFooterNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/module/fabric/ScreenStackNativeComponent.js +2 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -1
- package/lib/module/fabric/SearchBarNativeComponent.js +2 -0
- package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -1
- package/lib/module/index.js +8 -6
- package/lib/module/index.js.map +1 -1
- package/lib/module/native-stack/contexts/GHContext.js +2 -0
- package/lib/module/native-stack/contexts/GHContext.js.map +1 -1
- package/lib/module/native-stack/views/FooterComponent.js +11 -0
- package/lib/module/native-stack/views/FooterComponent.js.map +1 -0
- package/lib/module/native-stack/views/NativeStackView.js +61 -15
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
- package/lib/typescript/components/Screen.d.ts.map +1 -1
- package/lib/typescript/components/Screen.web.d.ts.map +1 -1
- package/lib/typescript/components/ScreenContainer.d.ts.map +1 -1
- package/lib/typescript/components/ScreenContentWrapper.d.ts +6 -0
- package/lib/typescript/components/ScreenContentWrapper.d.ts.map +1 -0
- package/lib/typescript/components/ScreenFooter.d.ts +12 -0
- package/lib/typescript/components/ScreenFooter.d.ts.map +1 -0
- package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
- package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
- package/lib/typescript/components/SearchBar.d.ts.map +1 -1
- package/lib/typescript/core.d.ts.map +1 -1
- package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +2 -3
- package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/NativeScreensModule.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenContentWrapperNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenContentWrapperNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/ScreenFooterNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenFooterNativeComponent.d.ts.map +1 -0
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +10 -4
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +20 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/native-stack/contexts/GHContext.d.ts.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +72 -22
- package/lib/typescript/native-stack/types.d.ts.map +1 -1
- package/lib/typescript/native-stack/views/FooterComponent.d.ts +7 -0
- package/lib/typescript/native-stack/views/FooterComponent.d.ts.map +1 -0
- package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +71 -18
- package/lib/typescript/types.d.ts.map +1 -1
- package/native-stack/README.md +40 -14
- package/package.json +1 -1
- package/react-native.config.js +18 -16
- package/src/TransitionProgressContext.tsx +2 -0
- package/src/components/Screen.tsx +76 -4
- package/src/components/Screen.web.tsx +3 -0
- package/src/components/ScreenContainer.tsx +2 -0
- package/src/components/ScreenContentWrapper.tsx +12 -0
- package/src/components/ScreenFooter.tsx +18 -0
- package/src/components/ScreenStack.tsx +2 -0
- package/src/components/ScreenStackHeaderConfig.tsx +2 -0
- package/src/components/SearchBar.tsx +2 -0
- package/src/core.ts +2 -0
- package/src/fabric/FullWindowOverlayNativeComponent.ts +2 -0
- package/src/fabric/ModalScreenNativeComponent.ts +4 -4
- package/src/fabric/NativeScreensModule.ts +2 -0
- package/src/fabric/ScreenContainerNativeComponent.ts +2 -0
- package/src/fabric/ScreenContentWrapperNativeComponent.ts +9 -0
- package/src/fabric/ScreenFooterNativeComponent.ts +6 -0
- package/src/fabric/ScreenNativeComponent.ts +15 -5
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +2 -0
- package/src/fabric/ScreenStackNativeComponent.ts +2 -0
- package/src/fabric/SearchBarNativeComponent.ts +2 -0
- package/src/index.tsx +16 -6
- package/src/native-stack/contexts/GHContext.tsx +2 -0
- package/src/native-stack/types.tsx +66 -22
- package/src/native-stack/views/FooterComponent.tsx +10 -0
- package/src/native-stack/views/NativeStackView.tsx +75 -11
- package/src/types.tsx +78 -17
- package/windows/RNScreens/Screen.h +3 -1
- /package/android/src/main/res/base/anim/{rns_slide_in_from_left_ios.xml → rns_ios_from_right_background_close.xml} +0 -0
- /package/android/src/main/res/base/anim/{rns_slide_out_to_right_ios.xml → rns_ios_from_right_foreground_close.xml} +0 -0
- /package/android/src/main/res/base/anim/{rns_slide_in_from_right_ios.xml → rns_ios_from_right_foreground_open.xml} +0 -0
package/README.md
CHANGED
|
@@ -188,7 +188,7 @@ To take advantage of the native stack navigator primitive for React Navigation t
|
|
|
188
188
|
|
|
189
189
|
## `FullWindowOverlay`
|
|
190
190
|
|
|
191
|
-
Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/
|
|
191
|
+
Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/apps/src/tests/Test1096.tsx
|
|
192
192
|
|
|
193
193
|
## Interop with [react-native-navigation](https://github.com/wix/react-native-navigation)
|
|
194
194
|
|
package/android/build.gradle
CHANGED
|
@@ -9,7 +9,11 @@ buildscript {
|
|
|
9
9
|
rnsDefaultKotlinVersion = '1.8.0'
|
|
10
10
|
}
|
|
11
11
|
ext.safeExtGet = {prop, fallback ->
|
|
12
|
-
|
|
12
|
+
def props = (prop instanceof String) ? [prop] : prop
|
|
13
|
+
def result = props.find { key ->
|
|
14
|
+
return rootProject.ext.has(key)
|
|
15
|
+
}
|
|
16
|
+
return result ? rootProject.ext.get(result) : fallback
|
|
13
17
|
}
|
|
14
18
|
repositories {
|
|
15
19
|
google()
|
|
@@ -77,8 +81,8 @@ android {
|
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
defaultConfig {
|
|
80
|
-
minSdkVersion safeExtGet('minSdkVersion', rnsDefaultMinSdkVersion)
|
|
81
|
-
targetSdkVersion safeExtGet('targetSdkVersion', rnsDefaultTargetSdkVersion)
|
|
84
|
+
minSdkVersion safeExtGet(['minSdkVersion', 'minSdk'], rnsDefaultMinSdkVersion)
|
|
85
|
+
targetSdkVersion safeExtGet(['targetSdkVersion', 'targetSdk'], rnsDefaultTargetSdkVersion)
|
|
82
86
|
versionCode 1
|
|
83
87
|
versionName "1.0"
|
|
84
88
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", IS_NEW_ARCHITECTURE_ENABLED.toString()
|
|
@@ -136,7 +140,7 @@ android {
|
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
res {
|
|
139
|
-
if (safeExtGet('compileSdkVersion', rnsDefaultCompileSdkVersion) >= 33) {
|
|
143
|
+
if (safeExtGet(['compileSdkVersion', 'compileSdk'], rnsDefaultCompileSdkVersion) >= 33) {
|
|
140
144
|
srcDirs = ["${androidResDir}/base", "${androidResDir}/v33"]
|
|
141
145
|
} else {
|
|
142
146
|
srcDirs = ["${androidResDir}/base"]
|
|
@@ -148,10 +152,26 @@ android {
|
|
|
148
152
|
repositories {
|
|
149
153
|
maven {
|
|
150
154
|
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
151
|
-
|
|
155
|
+
|
|
156
|
+
// First look for the standard location of react-native, as in RN Hello World template
|
|
152
157
|
// https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/local-cli/templates/HelloWorld/android/build.gradle#L21
|
|
153
|
-
|
|
158
|
+
// TODO(kkafar): Note, that in latest template app https://github.com/react-native-community/template/blob/0f4745b7a9d84232aeedec2def8d75ab9b050d11/template/android/build.gradle
|
|
159
|
+
// this is not specified at all.
|
|
160
|
+
File standardRnAndroidDirLocation = file("$rootDir/../node_modules/react-native/android")
|
|
161
|
+
if (standardRnAndroidDirLocation.exists()) {
|
|
162
|
+
url standardRnAndroidDirLocation
|
|
163
|
+
} else {
|
|
164
|
+
// We're in non standard setup - try to use node resolver to locate the react-native package.
|
|
165
|
+
File reactNativePackage = file(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim())
|
|
166
|
+
def rnAndroidDirLocation = "$reactNativePackage.parentFile/android"
|
|
167
|
+
if (reactNativePackage.exists()) {
|
|
168
|
+
url rnAndroidDirLocation
|
|
169
|
+
} else {
|
|
170
|
+
println "[RNScreens] Failed to resolve react-native directory. Attempted locations: ${standardRnAndroidDirLocation}, ${rnAndroidDirLocation}"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
154
173
|
}
|
|
174
|
+
|
|
155
175
|
mavenCentral()
|
|
156
176
|
mavenLocal()
|
|
157
177
|
google()
|
|
@@ -159,8 +179,8 @@ repositories {
|
|
|
159
179
|
|
|
160
180
|
dependencies {
|
|
161
181
|
implementation 'com.facebook.react:react-native:+'
|
|
162
|
-
implementation 'androidx.appcompat:appcompat:1.
|
|
163
|
-
implementation 'androidx.fragment:fragment:1.
|
|
182
|
+
implementation 'androidx.appcompat:appcompat:1.6.1'
|
|
183
|
+
implementation 'androidx.fragment:fragment-ktx:1.6.1'
|
|
164
184
|
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
|
|
165
185
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
|
166
186
|
implementation 'com.google.android.material:material:1.6.1'
|
|
@@ -24,7 +24,7 @@ abstract class FabricEnabledViewGroup(
|
|
|
24
24
|
protected fun updateScreenSizeFabric(
|
|
25
25
|
width: Int,
|
|
26
26
|
height: Int,
|
|
27
|
-
headerHeight:
|
|
27
|
+
headerHeight: Int,
|
|
28
28
|
) {
|
|
29
29
|
updateState(width, height, headerHeight)
|
|
30
30
|
}
|
|
@@ -33,10 +33,11 @@ abstract class FabricEnabledViewGroup(
|
|
|
33
33
|
fun updateState(
|
|
34
34
|
width: Int,
|
|
35
35
|
height: Int,
|
|
36
|
-
headerHeight:
|
|
36
|
+
headerHeight: Int,
|
|
37
37
|
) {
|
|
38
38
|
val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat())
|
|
39
39
|
val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat())
|
|
40
|
+
val realHeaderHeight: Float = PixelUtil.toDIPFromPixel(headerHeight.toFloat())
|
|
40
41
|
|
|
41
42
|
// Check incoming state values. If they're already the correct value, return early to prevent
|
|
42
43
|
// infinite UpdateState/SetState loop.
|
|
@@ -54,7 +55,7 @@ abstract class FabricEnabledViewGroup(
|
|
|
54
55
|
putDouble("frameWidth", realWidth.toDouble())
|
|
55
56
|
putDouble("frameHeight", realHeight.toDouble())
|
|
56
57
|
putDouble("contentOffsetX", 0.0)
|
|
57
|
-
putDouble("contentOffsetY",
|
|
58
|
+
putDouble("contentOffsetY", realHeaderHeight.toDouble())
|
|
58
59
|
}
|
|
59
60
|
mStateWrapper?.updateState(map)
|
|
60
61
|
}
|
|
@@ -2,11 +2,50 @@ package com.swmansion.rnscreens
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
+
import android.os.Build
|
|
5
6
|
import androidx.appcompat.widget.Toolbar
|
|
7
|
+
import com.facebook.react.modules.core.ChoreographerCompat
|
|
8
|
+
import com.facebook.react.modules.core.ReactChoreographer
|
|
6
9
|
|
|
7
10
|
// This class is used to store config closer to search bar
|
|
8
11
|
@SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated.
|
|
9
12
|
open class CustomToolbar(
|
|
10
13
|
context: Context,
|
|
11
14
|
val config: ScreenStackHeaderConfig,
|
|
12
|
-
) : Toolbar(context)
|
|
15
|
+
) : Toolbar(context) {
|
|
16
|
+
private var isLayoutEnqueued = false
|
|
17
|
+
private val layoutCallback: ChoreographerCompat.FrameCallback =
|
|
18
|
+
object : ChoreographerCompat.FrameCallback() {
|
|
19
|
+
override fun doFrame(frameTimeNanos: Long) {
|
|
20
|
+
isLayoutEnqueued = false
|
|
21
|
+
measure(
|
|
22
|
+
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
|
23
|
+
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
|
|
24
|
+
)
|
|
25
|
+
layout(left, top, right, bottom)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun requestLayout() {
|
|
30
|
+
super.requestLayout()
|
|
31
|
+
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
|
32
|
+
// Below Android API 29, layout is not being requested when subviews are being added to the layout,
|
|
33
|
+
// leading to having their subviews in position 0,0 of the toolbar (as Android don't calculate
|
|
34
|
+
// the position of each subview, even if Yoga has correctly set their width and height).
|
|
35
|
+
// This is mostly the issue, when windowSoftInputMode is set to adjustPan in AndroidManifest.
|
|
36
|
+
// Thus, we're manually calling the layout **after** the current layout.
|
|
37
|
+
@Suppress("SENSELESS_COMPARISON") // mLayoutCallback can be null here since this method can be called in init
|
|
38
|
+
if (!isLayoutEnqueued && layoutCallback != null) {
|
|
39
|
+
isLayoutEnqueued = true
|
|
40
|
+
// we use NATIVE_ANIMATED_MODULE choreographer queue because it allows us to catch the current
|
|
41
|
+
// looper loop instead of enqueueing the update in the next loop causing a one frame delay.
|
|
42
|
+
ReactChoreographer
|
|
43
|
+
.getInstance()
|
|
44
|
+
.postFrameCallback(
|
|
45
|
+
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
|
|
46
|
+
layoutCallback,
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import androidx.core.view.OnApplyWindowInsetsListener
|
|
5
|
+
import androidx.core.view.ViewCompat
|
|
6
|
+
import androidx.core.view.WindowInsetsCompat
|
|
7
|
+
import java.lang.ref.WeakReference
|
|
8
|
+
|
|
9
|
+
object InsetsObserverProxy : OnApplyWindowInsetsListener {
|
|
10
|
+
private val listeners: ArrayList<OnApplyWindowInsetsListener> = arrayListOf()
|
|
11
|
+
private var eventSourceView: WeakReference<View> = WeakReference(null)
|
|
12
|
+
|
|
13
|
+
// Please note semantics of this property. This is not `isRegistered`, because somebody, could unregister
|
|
14
|
+
// us, without our knowledge, e.g. reanimated or different 3rd party library. This holds only information
|
|
15
|
+
// whether this observer has been initially registered.
|
|
16
|
+
private var hasBeenRegistered: Boolean = false
|
|
17
|
+
|
|
18
|
+
private var shouldForwardInsetsToView = true
|
|
19
|
+
|
|
20
|
+
override fun onApplyWindowInsets(
|
|
21
|
+
v: View,
|
|
22
|
+
insets: WindowInsetsCompat,
|
|
23
|
+
): WindowInsetsCompat {
|
|
24
|
+
var rollingInsets =
|
|
25
|
+
if (shouldForwardInsetsToView) {
|
|
26
|
+
WindowInsetsCompat.toWindowInsetsCompat(
|
|
27
|
+
v.onApplyWindowInsets(insets.toWindowInsets()),
|
|
28
|
+
v,
|
|
29
|
+
)
|
|
30
|
+
} else {
|
|
31
|
+
insets
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
listeners.forEach {
|
|
35
|
+
rollingInsets = it.onApplyWindowInsets(v, insets)
|
|
36
|
+
}
|
|
37
|
+
return rollingInsets
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fun addOnApplyWindowInsetsListener(listener: OnApplyWindowInsetsListener) {
|
|
41
|
+
listeners.add(listener)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fun removeOnApplyWindowInsetsListener(listener: OnApplyWindowInsetsListener) {
|
|
45
|
+
listeners.remove(listener)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fun registerOnView(view: View) {
|
|
49
|
+
if (!hasBeenRegistered) {
|
|
50
|
+
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
|
51
|
+
eventSourceView = WeakReference(view)
|
|
52
|
+
hasBeenRegistered = true
|
|
53
|
+
} else if (getObservedView() != view) {
|
|
54
|
+
throw IllegalStateException(
|
|
55
|
+
"[RNScreens] Attempt to register InsetsObserverProxy on $view while it has been already registered on ${getObservedView()}",
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fun unregister() {
|
|
61
|
+
eventSourceView.get()?.takeIf { hasBeenRegistered }?.let {
|
|
62
|
+
ViewCompat.setOnApplyWindowInsetsListener(it, null)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private fun getObservedView(): View? = eventSourceView.get()
|
|
67
|
+
}
|
|
@@ -5,27 +5,39 @@ import android.content.pm.ActivityInfo
|
|
|
5
5
|
import android.graphics.Paint
|
|
6
6
|
import android.os.Parcelable
|
|
7
7
|
import android.util.SparseArray
|
|
8
|
-
import android.util.TypedValue
|
|
9
8
|
import android.view.View
|
|
10
9
|
import android.view.ViewGroup
|
|
11
10
|
import android.view.WindowManager
|
|
12
11
|
import android.webkit.WebView
|
|
12
|
+
import android.widget.ImageView
|
|
13
|
+
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
13
14
|
import androidx.core.view.children
|
|
14
15
|
import androidx.fragment.app.Fragment
|
|
16
|
+
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
15
17
|
import com.facebook.react.bridge.GuardedRunnable
|
|
16
18
|
import com.facebook.react.bridge.ReactContext
|
|
17
|
-
import com.facebook.react.uimanager.PixelUtil
|
|
18
19
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
19
20
|
import com.facebook.react.uimanager.UIManagerModule
|
|
21
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
22
|
+
import com.facebook.react.views.scroll.ReactScrollView
|
|
23
|
+
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
20
24
|
import com.swmansion.rnscreens.events.HeaderHeightChangeEvent
|
|
25
|
+
import com.swmansion.rnscreens.events.SheetDetentChangedEvent
|
|
21
26
|
|
|
22
27
|
@SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated.
|
|
23
28
|
class Screen(
|
|
24
|
-
|
|
25
|
-
) : FabricEnabledViewGroup(
|
|
29
|
+
val reactContext: ReactContext,
|
|
30
|
+
) : FabricEnabledViewGroup(reactContext),
|
|
31
|
+
ScreenContentWrapper.OnLayoutCallback {
|
|
26
32
|
val fragment: Fragment?
|
|
27
33
|
get() = fragmentWrapper?.fragment
|
|
28
34
|
|
|
35
|
+
val sheetBehavior: BottomSheetBehavior<Screen>?
|
|
36
|
+
get() = (layoutParams as? CoordinatorLayout.LayoutParams)?.behavior as? BottomSheetBehavior<Screen>
|
|
37
|
+
|
|
38
|
+
val reactEventDispatcher: EventDispatcher?
|
|
39
|
+
get() = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
|
|
40
|
+
|
|
29
41
|
var fragmentWrapper: ScreenFragmentWrapper? = null
|
|
30
42
|
var container: ScreenContainer? = null
|
|
31
43
|
var activityState: ActivityState? = null
|
|
@@ -40,6 +52,33 @@ class Screen(
|
|
|
40
52
|
var isStatusBarAnimated: Boolean? = null
|
|
41
53
|
var isBeingRemoved = false
|
|
42
54
|
|
|
55
|
+
// Props for controlling modal presentation
|
|
56
|
+
var isSheetGrabberVisible: Boolean = false
|
|
57
|
+
var sheetCornerRadius: Float = 0F
|
|
58
|
+
set(value) {
|
|
59
|
+
field = value
|
|
60
|
+
(fragment as? ScreenStackFragment)?.onSheetCornerRadiusChange()
|
|
61
|
+
}
|
|
62
|
+
var sheetExpandsWhenScrolledToEdge: Boolean = true
|
|
63
|
+
|
|
64
|
+
// We want to make sure here that at least one value is present in this array all the time.
|
|
65
|
+
// TODO: Model this with custom data structure to guarantee that this invariant is not violated.
|
|
66
|
+
var sheetDetents = mutableListOf(1.0)
|
|
67
|
+
var sheetLargestUndimmedDetentIndex: Int = -1
|
|
68
|
+
var sheetInitialDetentIndex: Int = 0
|
|
69
|
+
var sheetClosesOnTouchOutside = true
|
|
70
|
+
var sheetElevation: Float = 24F
|
|
71
|
+
|
|
72
|
+
var footer: ScreenFooter? = null
|
|
73
|
+
set(value) {
|
|
74
|
+
if (value == null && field != null) {
|
|
75
|
+
sheetBehavior?.let { field!!.unregisterWithSheetBehavior(it) }
|
|
76
|
+
} else if (value != null) {
|
|
77
|
+
sheetBehavior?.let { value.registerWithSheetBehavior(it) }
|
|
78
|
+
}
|
|
79
|
+
field = value
|
|
80
|
+
}
|
|
81
|
+
|
|
43
82
|
init {
|
|
44
83
|
// we set layout params as WindowManager.LayoutParams to workaround the issue with TextInputs
|
|
45
84
|
// not displaying modal menus (e.g., copy/paste or selection). The missing menus are due to the
|
|
@@ -54,6 +93,33 @@ class Screen(
|
|
|
54
93
|
layoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_APPLICATION)
|
|
55
94
|
}
|
|
56
95
|
|
|
96
|
+
/**
|
|
97
|
+
* ScreenContentWrapper notifies us here on it's layout. It is essential for implementing
|
|
98
|
+
* `fitToContents` for formSheets, as this is first entry point where we can acquire
|
|
99
|
+
* height of our content.
|
|
100
|
+
*/
|
|
101
|
+
override fun onLayoutCallback(
|
|
102
|
+
changed: Boolean,
|
|
103
|
+
left: Int,
|
|
104
|
+
top: Int,
|
|
105
|
+
right: Int,
|
|
106
|
+
bottom: Int,
|
|
107
|
+
) {
|
|
108
|
+
val height = bottom - top
|
|
109
|
+
|
|
110
|
+
if (sheetDetents.count() == 1 && sheetDetents.first() == SHEET_FIT_TO_CONTENTS) {
|
|
111
|
+
sheetBehavior?.let {
|
|
112
|
+
if (it.maxHeight != height) {
|
|
113
|
+
it.maxHeight = height
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fun registerLayoutCallbackForWrapper(wrapper: ScreenContentWrapper) {
|
|
120
|
+
wrapper.delegate = this
|
|
121
|
+
}
|
|
122
|
+
|
|
57
123
|
override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
|
|
58
124
|
// do nothing, react native will keep the view hierarchy so no need to serialize/deserialize
|
|
59
125
|
// view's states. The side effect of restoring is that TextInput components would trigger
|
|
@@ -75,16 +141,14 @@ class Screen(
|
|
|
75
141
|
val width = r - l
|
|
76
142
|
val height = b - t
|
|
77
143
|
|
|
78
|
-
val headerHeight = calculateHeaderHeight()
|
|
79
|
-
val totalHeight =
|
|
80
|
-
headerHeight.first + headerHeight.second // action bar height + status bar height
|
|
81
144
|
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
82
|
-
updateScreenSizeFabric(width, height,
|
|
145
|
+
updateScreenSizeFabric(width, height, t)
|
|
83
146
|
} else {
|
|
84
147
|
updateScreenSizePaper(width, height)
|
|
85
148
|
}
|
|
86
149
|
|
|
87
|
-
|
|
150
|
+
footer?.onParentLayout(changed, l, t, r, b, container!!.height)
|
|
151
|
+
notifyHeaderHeightChange(t)
|
|
88
152
|
}
|
|
89
153
|
}
|
|
90
154
|
|
|
@@ -92,7 +156,6 @@ class Screen(
|
|
|
92
156
|
width: Int,
|
|
93
157
|
height: Int,
|
|
94
158
|
) {
|
|
95
|
-
val reactContext = context as ReactContext
|
|
96
159
|
reactContext.runOnNativeModulesQueueThread(
|
|
97
160
|
object : GuardedRunnable(reactContext.exceptionHandler) {
|
|
98
161
|
override fun runGuarded() {
|
|
@@ -127,7 +190,14 @@ class Screen(
|
|
|
127
190
|
)
|
|
128
191
|
}
|
|
129
192
|
|
|
130
|
-
fun isTransparent(): Boolean =
|
|
193
|
+
fun isTransparent(): Boolean =
|
|
194
|
+
when (stackPresentation) {
|
|
195
|
+
StackPresentation.TRANSPARENT_MODAL,
|
|
196
|
+
StackPresentation.FORM_SHEET,
|
|
197
|
+
-> true
|
|
198
|
+
|
|
199
|
+
else -> false
|
|
200
|
+
}
|
|
131
201
|
|
|
132
202
|
private fun hasWebView(viewGroup: ViewGroup): Boolean {
|
|
133
203
|
for (i in 0 until viewGroup.childCount) {
|
|
@@ -295,7 +365,7 @@ class Screen(
|
|
|
295
365
|
parent?.let {
|
|
296
366
|
for (i in 0 until it.childCount) {
|
|
297
367
|
val child = it.getChildAt(i)
|
|
298
|
-
if (child
|
|
368
|
+
if (parent is SwipeRefreshLayout && child is ImageView) {
|
|
299
369
|
// SwipeRefreshLayout class which has CircleImageView as a child,
|
|
300
370
|
// does not handle `startViewTransition` properly.
|
|
301
371
|
// It has a custom `getChildDrawingOrder` method which returns
|
|
@@ -312,38 +382,22 @@ class Screen(
|
|
|
312
382
|
startTransitionRecursive(child.toolbar)
|
|
313
383
|
}
|
|
314
384
|
if (child is ViewGroup) {
|
|
385
|
+
// The children are miscounted when there's a FlatList with
|
|
386
|
+
// removeCLippedSubviews set to true (default).
|
|
387
|
+
// We add a simple view for each item in the list to make it work as expected.
|
|
388
|
+
// See https://github.com/software-mansion/react-native-screens/issues/2282
|
|
389
|
+
if (it is ReactScrollView && it.removeClippedSubviews) {
|
|
390
|
+
for (j in 0 until child.childCount) {
|
|
391
|
+
child.addView(View(context))
|
|
392
|
+
}
|
|
393
|
+
}
|
|
315
394
|
startTransitionRecursive(child)
|
|
316
395
|
}
|
|
317
396
|
}
|
|
318
397
|
}
|
|
319
398
|
}
|
|
320
399
|
|
|
321
|
-
private fun
|
|
322
|
-
val actionBarTv = TypedValue()
|
|
323
|
-
val resolvedActionBarSize =
|
|
324
|
-
context.theme.resolveAttribute(android.R.attr.actionBarSize, actionBarTv, true)
|
|
325
|
-
|
|
326
|
-
// Check if it's possible to get an attribute from theme context and assign a value from it.
|
|
327
|
-
// Otherwise, the default value will be returned.
|
|
328
|
-
val actionBarHeight =
|
|
329
|
-
TypedValue
|
|
330
|
-
.complexToDimensionPixelSize(actionBarTv.data, resources.displayMetrics)
|
|
331
|
-
.takeIf { resolvedActionBarSize && headerConfig?.isHeaderHidden != true && headerConfig?.isHeaderTranslucent != true }
|
|
332
|
-
?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() } ?: 0.0
|
|
333
|
-
|
|
334
|
-
val statusBarHeight =
|
|
335
|
-
context.resources
|
|
336
|
-
.getIdentifier("status_bar_height", "dimen", "android")
|
|
337
|
-
// Count only status bar when action bar is visible and status bar is not hidden
|
|
338
|
-
.takeIf { it > 0 && isStatusBarHidden != true && actionBarHeight > 0 }
|
|
339
|
-
?.let { (context.resources::getDimensionPixelSize)(it) }
|
|
340
|
-
?.let { PixelUtil.toDIPFromPixel(it.toFloat()).toDouble() }
|
|
341
|
-
?: 0.0
|
|
342
|
-
|
|
343
|
-
return actionBarHeight to statusBarHeight
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
private fun notifyHeaderHeightChange(headerHeight: Double) {
|
|
400
|
+
private fun notifyHeaderHeightChange(headerHeight: Int) {
|
|
347
401
|
val screenContext = context as ReactContext
|
|
348
402
|
val surfaceId = UIManagerHelper.getSurfaceId(screenContext)
|
|
349
403
|
UIManagerHelper
|
|
@@ -351,10 +405,26 @@ class Screen(
|
|
|
351
405
|
?.dispatchEvent(HeaderHeightChangeEvent(surfaceId, id, headerHeight))
|
|
352
406
|
}
|
|
353
407
|
|
|
408
|
+
internal fun notifySheetDetentChange(
|
|
409
|
+
detentIndex: Int,
|
|
410
|
+
isStable: Boolean,
|
|
411
|
+
) {
|
|
412
|
+
val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
|
|
413
|
+
reactEventDispatcher?.dispatchEvent(
|
|
414
|
+
SheetDetentChangedEvent(
|
|
415
|
+
surfaceId,
|
|
416
|
+
id,
|
|
417
|
+
detentIndex,
|
|
418
|
+
isStable,
|
|
419
|
+
),
|
|
420
|
+
)
|
|
421
|
+
}
|
|
422
|
+
|
|
354
423
|
enum class StackPresentation {
|
|
355
424
|
PUSH,
|
|
356
425
|
MODAL,
|
|
357
426
|
TRANSPARENT_MODAL,
|
|
427
|
+
FORM_SHEET,
|
|
358
428
|
}
|
|
359
429
|
|
|
360
430
|
enum class StackAnimation {
|
|
@@ -366,6 +436,8 @@ class Screen(
|
|
|
366
436
|
SLIDE_FROM_LEFT,
|
|
367
437
|
FADE_FROM_BOTTOM,
|
|
368
438
|
IOS,
|
|
439
|
+
IOS_FROM_RIGHT,
|
|
440
|
+
IOS_FROM_LEFT,
|
|
369
441
|
}
|
|
370
442
|
|
|
371
443
|
enum class ReplaceAnimation {
|
|
@@ -390,4 +462,13 @@ class Screen(
|
|
|
390
462
|
NAVIGATION_BAR_TRANSLUCENT,
|
|
391
463
|
NAVIGATION_BAR_HIDDEN,
|
|
392
464
|
}
|
|
465
|
+
|
|
466
|
+
companion object {
|
|
467
|
+
const val TAG = "Screen"
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* This value describes value in sheet detents array that will be treated as `fitToContents` option.
|
|
471
|
+
*/
|
|
472
|
+
const val SHEET_FIT_TO_CONTENTS = -1.0
|
|
473
|
+
}
|
|
393
474
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import com.facebook.react.bridge.ReactContext
|
|
5
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* When we wrap children of the Screen component inside this component in JS code,
|
|
9
|
+
* we can later use it to get the enclosing frame size of our content as it is rendered by RN.
|
|
10
|
+
*
|
|
11
|
+
* This is useful when adapting form sheet height to its contents height.
|
|
12
|
+
*/
|
|
13
|
+
@SuppressLint("ViewConstructor")
|
|
14
|
+
class ScreenContentWrapper(
|
|
15
|
+
reactContext: ReactContext,
|
|
16
|
+
) : ReactViewGroup(reactContext) {
|
|
17
|
+
internal var delegate: OnLayoutCallback? = null
|
|
18
|
+
|
|
19
|
+
interface OnLayoutCallback {
|
|
20
|
+
fun onLayoutCallback(
|
|
21
|
+
changed: Boolean,
|
|
22
|
+
left: Int,
|
|
23
|
+
top: Int,
|
|
24
|
+
right: Int,
|
|
25
|
+
bottom: Int,
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun onLayout(
|
|
30
|
+
changed: Boolean,
|
|
31
|
+
left: Int,
|
|
32
|
+
top: Int,
|
|
33
|
+
right: Int,
|
|
34
|
+
bottom: Int,
|
|
35
|
+
) {
|
|
36
|
+
delegate?.onLayoutCallback(changed, left, top, right, bottom)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
6
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
7
|
+
import com.facebook.react.viewmanagers.RNSScreenContentWrapperManagerDelegate
|
|
8
|
+
import com.facebook.react.viewmanagers.RNSScreenContentWrapperManagerInterface
|
|
9
|
+
|
|
10
|
+
@ReactModule(name = ScreenContentWrapperManager.REACT_CLASS)
|
|
11
|
+
class ScreenContentWrapperManager :
|
|
12
|
+
ViewGroupManager<ScreenContentWrapper>(),
|
|
13
|
+
RNSScreenContentWrapperManagerInterface<ScreenContentWrapper> {
|
|
14
|
+
private val delegate: ViewManagerDelegate<ScreenContentWrapper> = RNSScreenContentWrapperManagerDelegate(this)
|
|
15
|
+
|
|
16
|
+
companion object {
|
|
17
|
+
const val REACT_CLASS = "RNSScreenContentWrapper"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override fun getName(): String = REACT_CLASS
|
|
21
|
+
|
|
22
|
+
override fun createViewInstance(reactContext: ThemedReactContext): ScreenContentWrapper = ScreenContentWrapper(reactContext)
|
|
23
|
+
|
|
24
|
+
override fun getDelegate(): ViewManagerDelegate<ScreenContentWrapper> = delegate
|
|
25
|
+
}
|