react-native-keyboard-controller 1.2.0 → 1.4.0
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/android/build.gradle +0 -40
- package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardAnimationCallback.kt +8 -4
- package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardControllerPackage.kt +44 -8
- package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManagerImpl.kt +6 -3
- package/android/src/main/java/com/reactnativekeyboardcontroller/events/KeyboardTransitionEvent.kt +2 -6
- package/ios/.swiftlint.yml +4 -0
- package/ios/KeyboardController.xcodeproj/project.pbxproj +2 -2
- package/ios/KeyboardControllerModule.mm +1 -1
- package/ios/KeyboardControllerView.mm +28 -10
- package/ios/KeyboardControllerViewManager.mm +2 -0
- package/ios/KeyboardControllerViewManager.swift +4 -1
- package/ios/KeyboardMoveEvent.h +1 -0
- package/ios/KeyboardMoveEvent.m +2 -1
- package/ios/KeyboardMovementObserver.swift +89 -4
- package/lib/commonjs/animated.js +44 -63
- package/lib/commonjs/animated.js.map +1 -1
- package/lib/commonjs/context.js +29 -0
- package/lib/commonjs/context.js.map +1 -0
- package/lib/commonjs/hooks.js +64 -0
- package/lib/commonjs/hooks.js.map +1 -0
- package/lib/commonjs/index.js +39 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal.js +91 -0
- package/lib/commonjs/internal.js.map +1 -0
- package/lib/commonjs/monkey-patch.js +3 -3
- package/lib/commonjs/monkey-patch.js.map +1 -1
- package/lib/commonjs/native.js +24 -21
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/replicas.js +2 -2
- package/lib/commonjs/replicas.js.map +1 -1
- package/lib/commonjs/{KeyboardControllerViewNativeComponent.js → specs/KeyboardControllerViewNativeComponent.js} +0 -0
- package/lib/commonjs/{KeyboardControllerViewNativeComponent.js.map → specs/KeyboardControllerViewNativeComponent.js.map} +1 -1
- package/lib/commonjs/{NativeKeyboardController.js → specs/NativeKeyboardController.js} +0 -0
- package/lib/commonjs/{NativeKeyboardController.js.map → specs/NativeKeyboardController.js.map} +0 -0
- package/lib/commonjs/{NativeStatusBarManagerCompat.js → specs/NativeStatusBarManagerCompat.js} +0 -0
- package/lib/commonjs/{NativeStatusBarManagerCompat.js.map → specs/NativeStatusBarManagerCompat.js.map} +0 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils.js +11 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/animated.js +43 -55
- package/lib/module/animated.js.map +1 -1
- package/lib/module/context.js +19 -0
- package/lib/module/context.js.map +1 -0
- package/lib/module/hooks.js +39 -0
- package/lib/module/hooks.js.map +1 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal.js +80 -0
- package/lib/module/internal.js.map +1 -0
- package/lib/module/monkey-patch.js +4 -3
- package/lib/module/monkey-patch.js.map +1 -1
- package/lib/module/native.js +23 -17
- package/lib/module/native.js.map +1 -1
- package/lib/module/replicas.js +1 -1
- package/lib/module/replicas.js.map +1 -1
- package/lib/module/{KeyboardControllerViewNativeComponent.js → specs/KeyboardControllerViewNativeComponent.js} +0 -0
- package/lib/module/{KeyboardControllerViewNativeComponent.js.map → specs/KeyboardControllerViewNativeComponent.js.map} +1 -1
- package/lib/module/{NativeKeyboardController.js → specs/NativeKeyboardController.js} +0 -0
- package/lib/module/{NativeKeyboardController.js.map → specs/NativeKeyboardController.js.map} +0 -0
- package/lib/module/{NativeStatusBarManagerCompat.js → specs/NativeStatusBarManagerCompat.js} +0 -0
- package/lib/module/{NativeStatusBarManagerCompat.js.map → specs/NativeStatusBarManagerCompat.js.map} +0 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils.js +2 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/animated.d.ts +1 -17
- package/lib/typescript/context.d.ts +18 -0
- package/lib/typescript/hooks.d.ts +8 -0
- package/lib/typescript/index.d.ts +3 -0
- package/lib/typescript/internal.d.ts +21 -0
- package/lib/typescript/native.d.ts +14 -26
- package/lib/typescript/{KeyboardControllerViewNativeComponent.d.ts → specs/KeyboardControllerViewNativeComponent.d.ts} +2 -0
- package/lib/typescript/{NativeKeyboardController.d.ts → specs/NativeKeyboardController.d.ts} +0 -0
- package/lib/typescript/{NativeStatusBarManagerCompat.d.ts → specs/NativeStatusBarManagerCompat.d.ts} +0 -0
- package/lib/typescript/types.d.ts +32 -0
- package/lib/typescript/utils.d.ts +1 -0
- package/package.json +17 -20
- package/react-native-keyboard-controller.podspec +2 -1
- package/src/animated.tsx +42 -78
- package/src/context.ts +31 -0
- package/src/hooks.ts +56 -0
- package/src/index.ts +3 -0
- package/src/internal.ts +87 -0
- package/src/{monkey-patch.tsx → monkey-patch.ts} +3 -6
- package/src/native.ts +37 -66
- package/src/replicas.ts +1 -1
- package/src/{KeyboardControllerViewNativeComponent.ts → specs/KeyboardControllerViewNativeComponent.ts} +4 -0
- package/src/{NativeKeyboardController.ts → specs/NativeKeyboardController.ts} +0 -0
- package/src/{NativeStatusBarManagerCompat.ts → specs/NativeStatusBarManagerCompat.ts} +0 -0
- package/src/types.ts +60 -0
- package/src/utils.ts +1 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +0 -5
- package/android/gradlew +0 -185
- package/android/gradlew.bat +0 -89
- package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerComponentsRegistry.kt +0 -31
- package/android/src/main/jni/Android.mk +0 -42
- package/android/src/main/jni/KeyboardControllerComponentsRegistry.cpp +0 -71
- package/android/src/main/jni/KeyboardControllerComponentsRegistry.h +0 -35
- package/android/src/main/jni/OnLoad.cpp +0 -9
- package/lib/commonjs/architecture.js +0 -13
- package/lib/commonjs/architecture.js.map +0 -1
- package/lib/module/architecture.js +0 -5
- package/lib/module/architecture.js.map +0 -1
- package/lib/typescript/architecture.d.ts +0 -2
- package/src/architecture.ts +0 -4
package/android/build.gradle
CHANGED
|
@@ -46,41 +46,11 @@ android {
|
|
|
46
46
|
versionCode 1
|
|
47
47
|
versionName "1.0"
|
|
48
48
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
49
|
-
if (isNewArchitectureEnabled()) {
|
|
50
|
-
var appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
|
|
51
|
-
externalNativeBuild {
|
|
52
|
-
ndkBuild {
|
|
53
|
-
arguments "APP_PLATFORM=android-21",
|
|
54
|
-
"APP_STL=c++_shared",
|
|
55
|
-
"NDK_TOOLCHAIN_VERSION=clang",
|
|
56
|
-
"GENERATED_SRC_DIR=${appProject.buildDir}/generated/source",
|
|
57
|
-
"PROJECT_BUILD_DIR=${appProject.buildDir}",
|
|
58
|
-
"REACT_ANDROID_DIR=${appProject.rootDir}/../node_modules/react-native/ReactAndroid",
|
|
59
|
-
"REACT_ANDROID_BUILD_DIR=${appProject.rootDir}/../node_modules/react-native/ReactAndroid/build"
|
|
60
|
-
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
|
61
|
-
cppFlags "-std=c++17"
|
|
62
|
-
targets "reactnativekeyboardcontroller_modules"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
49
|
ndk {
|
|
67
50
|
abiFilters (*reactNativeArchitectures())
|
|
68
51
|
}
|
|
69
52
|
}
|
|
70
53
|
|
|
71
|
-
if (isNewArchitectureEnabled()) {
|
|
72
|
-
externalNativeBuild {
|
|
73
|
-
ndkBuild {
|
|
74
|
-
path "src/main/jni/Android.mk"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
packagingOptions {
|
|
79
|
-
exclude "**/libreact_render_*.so"
|
|
80
|
-
exclude "**/librrc_root.so"
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
54
|
sourceSets {
|
|
85
55
|
main {
|
|
86
56
|
if (isNewArchitectureEnabled()) {
|
|
@@ -186,13 +156,3 @@ dependencies {
|
|
|
186
156
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
187
157
|
implementation 'androidx.core:core-ktx:1.5.0-beta03'
|
|
188
158
|
}
|
|
189
|
-
|
|
190
|
-
if (isNewArchitectureEnabled()) {
|
|
191
|
-
react {
|
|
192
|
-
reactNativeDir = rootProject.file("../node_modules/react-native/")
|
|
193
|
-
jsRootDir = file("../src/")
|
|
194
|
-
codegenDir = rootProject.file("../node_modules/react-native-codegen/")
|
|
195
|
-
libraryName = "reactnativekeyboardcontroller"
|
|
196
|
-
codegenJavaPackageName = "com.reactnativekeyboardcontroller"
|
|
197
|
-
}
|
|
198
|
-
}
|
package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardAnimationCallback.kt
CHANGED
|
@@ -74,14 +74,16 @@ class KeyboardAnimationCallback(
|
|
|
74
74
|
val keyboardHeight = getCurrentKeyboardHeight()
|
|
75
75
|
|
|
76
76
|
this.emitEvent("KeyboardController::keyboardWillShow", getEventParams(keyboardHeight))
|
|
77
|
+
this.sendEventToJS(KeyboardTransitionEvent(view.id, "topKeyboardMoveStart", keyboardHeight, 1.0))
|
|
77
78
|
|
|
78
|
-
val animation = ValueAnimator.ofInt(
|
|
79
|
+
val animation = ValueAnimator.ofInt(this.persistentKeyboardHeight, keyboardHeight)
|
|
79
80
|
animation.addUpdateListener { animator ->
|
|
80
81
|
val toValue = animator.animatedValue as Int
|
|
81
|
-
this.sendEventToJS(KeyboardTransitionEvent(view.id, toValue,
|
|
82
|
+
this.sendEventToJS(KeyboardTransitionEvent(view.id, "topKeyboardMove", toValue, toValue.toDouble() / keyboardHeight))
|
|
82
83
|
}
|
|
83
84
|
animation.doOnEnd {
|
|
84
85
|
this.emitEvent("KeyboardController::keyboardDidShow", getEventParams(keyboardHeight))
|
|
86
|
+
this.sendEventToJS(KeyboardTransitionEvent(view.id, "topKeyboardMoveEnd", keyboardHeight, 1.0))
|
|
85
87
|
}
|
|
86
88
|
animation.setDuration(250).startDelay = 0
|
|
87
89
|
animation.start()
|
|
@@ -108,6 +110,7 @@ class KeyboardAnimationCallback(
|
|
|
108
110
|
this.emitEvent("KeyboardController::" + if (!isKeyboardVisible) "keyboardWillHide" else "keyboardWillShow", getEventParams(keyboardHeight))
|
|
109
111
|
|
|
110
112
|
Log.i(TAG, "HEIGHT:: $keyboardHeight")
|
|
113
|
+
this.sendEventToJS(KeyboardTransitionEvent(view.id, "topKeyboardMoveStart", keyboardHeight, if (!isKeyboardVisible) 0.0 else 1.0))
|
|
111
114
|
|
|
112
115
|
return super.onStart(animation, bounds)
|
|
113
116
|
}
|
|
@@ -128,7 +131,7 @@ class KeyboardAnimationCallback(
|
|
|
128
131
|
val diff = Insets.subtract(typesInset, otherInset).let {
|
|
129
132
|
Insets.max(it, Insets.NONE)
|
|
130
133
|
}
|
|
131
|
-
val diffY = (diff.
|
|
134
|
+
val diffY = (diff.bottom - diff.top).toFloat()
|
|
132
135
|
val height = toDp(diffY, context)
|
|
133
136
|
|
|
134
137
|
var progress = 0.0
|
|
@@ -139,7 +142,7 @@ class KeyboardAnimationCallback(
|
|
|
139
142
|
}
|
|
140
143
|
Log.i(TAG, "DiffY: $diffY $height $progress")
|
|
141
144
|
|
|
142
|
-
this.sendEventToJS(KeyboardTransitionEvent(view.id, height, progress))
|
|
145
|
+
this.sendEventToJS(KeyboardTransitionEvent(view.id, "topKeyboardMove", height, progress))
|
|
143
146
|
|
|
144
147
|
return insets
|
|
145
148
|
}
|
|
@@ -150,6 +153,7 @@ class KeyboardAnimationCallback(
|
|
|
150
153
|
isTransitioning = false
|
|
151
154
|
this.persistentKeyboardHeight = getCurrentKeyboardHeight()
|
|
152
155
|
this.emitEvent("KeyboardController::" + if (!isKeyboardVisible) "keyboardDidHide" else "keyboardDidShow", getEventParams(this.persistentKeyboardHeight))
|
|
156
|
+
this.sendEventToJS(KeyboardTransitionEvent(view.id, "topKeyboardMoveEnd", this.persistentKeyboardHeight, if (!isKeyboardVisible) 0.0 else 1.0))
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
private fun isKeyboardVisible(): Boolean {
|
package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardControllerPackage.kt
CHANGED
|
@@ -1,21 +1,57 @@
|
|
|
1
1
|
package com.reactnativekeyboardcontroller
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import androidx.annotation.Nullable
|
|
4
|
+
import com.facebook.react.TurboReactPackage
|
|
4
5
|
import com.facebook.react.bridge.NativeModule
|
|
5
6
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
8
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
6
9
|
import com.facebook.react.uimanager.ViewManager
|
|
7
|
-
import com.facebook.soloader.SoLoader
|
|
8
10
|
|
|
9
|
-
class KeyboardControllerPackage :
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
class KeyboardControllerPackage : TurboReactPackage() {
|
|
12
|
+
@Nullable
|
|
13
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
14
|
+
return when (name) {
|
|
15
|
+
KeyboardControllerModuleImpl.NAME -> {
|
|
16
|
+
KeyboardControllerModule(reactContext)
|
|
17
|
+
}
|
|
18
|
+
StatusBarManagerCompatImpl.NAME -> {
|
|
19
|
+
StatusBarManagerCompatModule(reactContext)
|
|
20
|
+
}
|
|
21
|
+
else -> {
|
|
22
|
+
null
|
|
23
|
+
}
|
|
24
|
+
}
|
|
12
25
|
}
|
|
13
26
|
|
|
14
|
-
override fun
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
28
|
+
return ReactModuleInfoProvider {
|
|
29
|
+
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
|
|
30
|
+
val isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
|
31
|
+
|
|
32
|
+
moduleInfos[KeyboardControllerModuleImpl.NAME] = ReactModuleInfo(
|
|
33
|
+
KeyboardControllerModuleImpl.NAME,
|
|
34
|
+
KeyboardControllerModuleImpl.NAME,
|
|
35
|
+
false, // canOverrideExistingModule
|
|
36
|
+
false, // needsEagerInit
|
|
37
|
+
true, // hasConstants
|
|
38
|
+
false, // isCxxModule
|
|
39
|
+
isTurboModule // isTurboModule
|
|
40
|
+
)
|
|
41
|
+
moduleInfos[StatusBarManagerCompatImpl.NAME] = ReactModuleInfo(
|
|
42
|
+
StatusBarManagerCompatImpl.NAME,
|
|
43
|
+
StatusBarManagerCompatImpl.NAME,
|
|
44
|
+
false, // canOverrideExistingModule
|
|
45
|
+
false, // needsEagerInit
|
|
46
|
+
true, // hasConstants
|
|
47
|
+
false, // isCxxModule
|
|
48
|
+
isTurboModule // isTurboModule
|
|
49
|
+
)
|
|
50
|
+
moduleInfos
|
|
17
51
|
}
|
|
52
|
+
}
|
|
18
53
|
|
|
54
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
19
55
|
return listOf(KeyboardControllerViewManager(reactContext))
|
|
20
56
|
}
|
|
21
57
|
}
|
package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManagerImpl.kt
CHANGED
|
@@ -9,7 +9,6 @@ import com.facebook.react.bridge.ReactApplicationContext
|
|
|
9
9
|
import com.facebook.react.common.MapBuilder
|
|
10
10
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
11
11
|
import com.facebook.react.views.view.ReactViewGroup
|
|
12
|
-
import com.reactnativekeyboardcontroller.events.KeyboardTransitionEvent
|
|
13
12
|
|
|
14
13
|
class KeyboardControllerViewManagerImpl(reactContext: ReactApplicationContext) {
|
|
15
14
|
private val TAG = KeyboardControllerViewManagerImpl::class.qualifiedName
|
|
@@ -58,8 +57,12 @@ class KeyboardControllerViewManagerImpl(reactContext: ReactApplicationContext) {
|
|
|
58
57
|
|
|
59
58
|
fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
|
|
60
59
|
val map: MutableMap<String, Any> = MapBuilder.of(
|
|
61
|
-
|
|
62
|
-
MapBuilder.of("registrationName", "onKeyboardMove")
|
|
60
|
+
"topKeyboardMove",
|
|
61
|
+
MapBuilder.of("registrationName", "onKeyboardMove"),
|
|
62
|
+
"topKeyboardMoveStart",
|
|
63
|
+
MapBuilder.of("registrationName", "onKeyboardMoveStart"),
|
|
64
|
+
"topKeyboardMoveEnd",
|
|
65
|
+
MapBuilder.of("registrationName", "onKeyboardMoveEnd"),
|
|
63
66
|
)
|
|
64
67
|
|
|
65
68
|
return map
|
package/android/src/main/java/com/reactnativekeyboardcontroller/events/KeyboardTransitionEvent.kt
CHANGED
|
@@ -4,8 +4,8 @@ import com.facebook.react.bridge.Arguments
|
|
|
4
4
|
import com.facebook.react.uimanager.events.Event
|
|
5
5
|
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
6
6
|
|
|
7
|
-
class KeyboardTransitionEvent(private val
|
|
8
|
-
override fun getEventName() =
|
|
7
|
+
class KeyboardTransitionEvent(viewId: Int, private val event: String, private val height: Int, private val progress: Double) : Event<KeyboardTransitionEvent>(viewId) {
|
|
8
|
+
override fun getEventName() = event
|
|
9
9
|
|
|
10
10
|
// TODO: All events for a given view can be coalesced?
|
|
11
11
|
override fun getCoalescingKey(): Short = 0
|
|
@@ -16,8 +16,4 @@ class KeyboardTransitionEvent(private val viewId: Int, private val height: Int,
|
|
|
16
16
|
map.putInt("height", height)
|
|
17
17
|
rctEventEmitter.receiveEvent(viewTag, eventName, map)
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
companion object {
|
|
21
|
-
const val EVENT_NAME = "topKeyboardMove"
|
|
22
|
-
}
|
|
23
19
|
}
|
package/ios/.swiftlint.yml
CHANGED
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
188
188
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
189
189
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
190
|
-
IPHONEOS_DEPLOYMENT_TARGET =
|
|
190
|
+
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
|
191
191
|
MTL_ENABLE_DEBUG_INFO = YES;
|
|
192
192
|
ONLY_ACTIVE_ARCH = YES;
|
|
193
193
|
SDKROOT = iphoneos;
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
231
231
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
232
232
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
233
|
-
IPHONEOS_DEPLOYMENT_TARGET =
|
|
233
|
+
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
|
234
234
|
MTL_ENABLE_DEBUG_INFO = NO;
|
|
235
235
|
SDKROOT = iphoneos;
|
|
236
236
|
VALIDATE_PRODUCT = YES;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// Thanks to this guard, we won't import this header when we build for the old architecture.
|
|
13
13
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
14
14
|
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
|
15
|
-
#import
|
|
15
|
+
#import <reactnativekeyboardcontroller/reactnativekeyboardcontroller.h>
|
|
16
16
|
#endif
|
|
17
17
|
|
|
18
18
|
#import "KeyboardControllerModule-Header.h"
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
#import "KeyboardMoveEvent.h"
|
|
13
13
|
#import "react_native_keyboard_controller-Swift.h"
|
|
14
14
|
|
|
15
|
-
#import <react/renderer/components/
|
|
16
|
-
#import <react/renderer/components/
|
|
17
|
-
#import <react/renderer/components/
|
|
18
|
-
#import <react/renderer/components/
|
|
15
|
+
#import <react/renderer/components/reactnativekeyboardcontroller/ComponentDescriptors.h>
|
|
16
|
+
#import <react/renderer/components/reactnativekeyboardcontroller/EventEmitters.h>
|
|
17
|
+
#import <react/renderer/components/reactnativekeyboardcontroller/Props.h>
|
|
18
|
+
#import <react/renderer/components/reactnativekeyboardcontroller/RCTComponentViewHelpers.h>
|
|
19
19
|
|
|
20
20
|
#import <React/RCTBridge+Private.h>
|
|
21
21
|
|
|
@@ -44,13 +44,30 @@ using namespace facebook::react;
|
|
|
44
44
|
_props = defaultProps;
|
|
45
45
|
|
|
46
46
|
observer = [[KeyboardMovementObserver alloc]
|
|
47
|
-
initWithHandler:^(NSNumber *height, NSNumber *progress) {
|
|
47
|
+
initWithHandler:^(NSString *event, NSNumber *height, NSNumber *progress) {
|
|
48
48
|
if (self->_eventEmitter) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
// TODO: use reflection to reduce code duplication?
|
|
50
|
+
if ([event isEqualToString:@"onKeyboardMoveStart"]) {
|
|
51
|
+
std::dynamic_pointer_cast<const facebook::react::KeyboardControllerViewEventEmitter>(
|
|
52
|
+
self->_eventEmitter)
|
|
53
|
+
->onKeyboardMoveStart(
|
|
54
|
+
facebook::react::KeyboardControllerViewEventEmitter::OnKeyboardMoveStart{
|
|
55
|
+
.height = [height intValue], .progress = [progress floatValue]});
|
|
56
|
+
}
|
|
57
|
+
if ([event isEqualToString:@"onKeyboardMove"]) {
|
|
58
|
+
std::dynamic_pointer_cast<const facebook::react::KeyboardControllerViewEventEmitter>(
|
|
59
|
+
self->_eventEmitter)
|
|
60
|
+
->onKeyboardMove(
|
|
61
|
+
facebook::react::KeyboardControllerViewEventEmitter::OnKeyboardMove{
|
|
62
|
+
.height = [height intValue], .progress = [progress floatValue]});
|
|
63
|
+
}
|
|
64
|
+
if ([event isEqualToString:@"onKeyboardMoveEnd"]) {
|
|
65
|
+
std::dynamic_pointer_cast<const facebook::react::KeyboardControllerViewEventEmitter>(
|
|
66
|
+
self->_eventEmitter)
|
|
67
|
+
->onKeyboardMoveEnd(
|
|
68
|
+
facebook::react::KeyboardControllerViewEventEmitter::OnKeyboardMoveEnd{
|
|
69
|
+
.height = [height intValue], .progress = [progress floatValue]});
|
|
70
|
+
}
|
|
54
71
|
}
|
|
55
72
|
|
|
56
73
|
// TODO: use built-in _eventEmitter once NativeAnimated module will use ModernEventemitter
|
|
@@ -58,6 +75,7 @@ using namespace facebook::react;
|
|
|
58
75
|
if (bridge) {
|
|
59
76
|
KeyboardMoveEvent *keyboardMoveEvent =
|
|
60
77
|
[[KeyboardMoveEvent alloc] initWithReactTag:@(self.tag)
|
|
78
|
+
event:event
|
|
61
79
|
height:height
|
|
62
80
|
progress:progress];
|
|
63
81
|
[bridge.eventDispatcher sendEvent:keyboardMoveEvent];
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
@interface RCT_EXTERN_MODULE (KeyboardControllerViewManager, RCTViewManager)
|
|
4
4
|
|
|
5
|
+
RCT_EXPORT_VIEW_PROPERTY(onKeyboardMoveStart, RCTDirectEventBlock);
|
|
5
6
|
RCT_EXPORT_VIEW_PROPERTY(onKeyboardMove, RCTDirectEventBlock);
|
|
7
|
+
RCT_EXPORT_VIEW_PROPERTY(onKeyboardMoveEnd, RCTDirectEventBlock);
|
|
6
8
|
|
|
7
9
|
@end
|
|
@@ -12,7 +12,9 @@ class KeyboardControllerViewManager: RCTViewManager {
|
|
|
12
12
|
class KeyboardControllerView: UIView {
|
|
13
13
|
private var keyboardObserver: KeyboardMovementObserver?
|
|
14
14
|
private var eventDispatcher: RCTEventDispatcherProtocol
|
|
15
|
+
@objc var onKeyboardMoveStart: RCTDirectEventBlock?
|
|
15
16
|
@objc var onKeyboardMove: RCTDirectEventBlock?
|
|
17
|
+
@objc var onKeyboardMoveEnd: RCTDirectEventBlock?
|
|
16
18
|
|
|
17
19
|
init(frame: CGRect, eventDispatcher: RCTEventDispatcherProtocol) {
|
|
18
20
|
self.eventDispatcher = eventDispatcher
|
|
@@ -39,10 +41,11 @@ class KeyboardControllerView: UIView {
|
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
func onEvent(height: NSNumber, progress: NSNumber) {
|
|
44
|
+
func onEvent(event: NSString, height: NSNumber, progress: NSNumber) {
|
|
43
45
|
eventDispatcher.send(
|
|
44
46
|
KeyboardMoveEvent(
|
|
45
47
|
reactTag: reactTag,
|
|
48
|
+
event: event as String,
|
|
46
49
|
height: height,
|
|
47
50
|
progress: progress
|
|
48
51
|
)
|
package/ios/KeyboardMoveEvent.h
CHANGED
package/ios/KeyboardMoveEvent.m
CHANGED
|
@@ -19,13 +19,14 @@
|
|
|
19
19
|
@synthesize eventName = _eventName;
|
|
20
20
|
|
|
21
21
|
- (instancetype)initWithReactTag:(NSNumber *)reactTag
|
|
22
|
+
event:(NSString *)event
|
|
22
23
|
height:(NSNumber *)height
|
|
23
24
|
progress:(NSNumber *)progress
|
|
24
25
|
{
|
|
25
26
|
RCTAssertParam(reactTag);
|
|
26
27
|
|
|
27
28
|
if ((self = [super init])) {
|
|
28
|
-
_eventName =
|
|
29
|
+
_eventName = [event copy];
|
|
29
30
|
_viewTag = reactTag;
|
|
30
31
|
_progress = progress;
|
|
31
32
|
_height = height;
|
|
@@ -10,10 +10,31 @@ import Foundation
|
|
|
10
10
|
|
|
11
11
|
@objc(KeyboardMovementObserver)
|
|
12
12
|
public class KeyboardMovementObserver: NSObject {
|
|
13
|
-
|
|
13
|
+
// class members
|
|
14
|
+
var onEvent: (NSString, NSNumber, NSNumber) -> Void
|
|
14
15
|
var onNotify: (String, Any) -> Void
|
|
16
|
+
// progress tracker
|
|
17
|
+
private var _keyboardView: UIView?
|
|
18
|
+
private var keyboardView: UIView? {
|
|
19
|
+
let windowsCount = UIApplication.shared.windows.count
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
if _keyboardView == nil || windowsCount != _windowsCount {
|
|
22
|
+
_keyboardView = findKeyboardView()
|
|
23
|
+
_windowsCount = windowsCount
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return _keyboardView
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private var _windowsCount: Int = 0
|
|
30
|
+
private var prevKeyboardPosition = 0.0
|
|
31
|
+
private var displayLink: CADisplayLink?
|
|
32
|
+
private var keyboardHeight: CGFloat = 0.0
|
|
33
|
+
|
|
34
|
+
@objc public init(
|
|
35
|
+
handler: @escaping (NSString, NSNumber, NSNumber) -> Void,
|
|
36
|
+
onNotify: @escaping (String, Any) -> Void
|
|
37
|
+
) {
|
|
17
38
|
onEvent = handler
|
|
18
39
|
self.onNotify = onNotify
|
|
19
40
|
}
|
|
@@ -53,12 +74,15 @@ public class KeyboardMovementObserver: NSObject {
|
|
|
53
74
|
@objc func keyboardWillAppear(_ notification: Notification) {
|
|
54
75
|
if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
|
|
55
76
|
let keyboardHeight = keyboardFrame.cgRectValue.size.height
|
|
77
|
+
self.keyboardHeight = keyboardHeight
|
|
56
78
|
|
|
57
79
|
var data = [AnyHashable: Any]()
|
|
58
80
|
data["height"] = keyboardHeight
|
|
59
81
|
|
|
60
|
-
onEvent(Float(
|
|
82
|
+
onEvent("onKeyboardMoveStart", Float(keyboardHeight) as NSNumber, 1)
|
|
61
83
|
onNotify("KeyboardController::keyboardWillShow", data)
|
|
84
|
+
|
|
85
|
+
setupKeyboardWatcher()
|
|
62
86
|
}
|
|
63
87
|
}
|
|
64
88
|
|
|
@@ -66,18 +90,24 @@ public class KeyboardMovementObserver: NSObject {
|
|
|
66
90
|
var data = [AnyHashable: Any]()
|
|
67
91
|
data["height"] = 0
|
|
68
92
|
|
|
69
|
-
onEvent(0, 0)
|
|
93
|
+
onEvent("onKeyboardMoveStart", 0, 0)
|
|
70
94
|
onNotify("KeyboardController::keyboardWillHide", data)
|
|
95
|
+
|
|
96
|
+
setupKeyboardWatcher()
|
|
71
97
|
}
|
|
72
98
|
|
|
73
99
|
@objc func keyboardDidAppear(_ notification: Notification) {
|
|
74
100
|
if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
|
|
75
101
|
let keyboardHeight = keyboardFrame.cgRectValue.size.height
|
|
102
|
+
self.keyboardHeight = keyboardHeight
|
|
76
103
|
|
|
77
104
|
var data = [AnyHashable: Any]()
|
|
78
105
|
data["height"] = keyboardHeight
|
|
79
106
|
|
|
107
|
+
onEvent("onKeyboardMoveEnd", keyboardHeight as NSNumber, 1)
|
|
80
108
|
onNotify("KeyboardController::keyboardDidShow", data)
|
|
109
|
+
|
|
110
|
+
removeKeyboardWatcher()
|
|
81
111
|
}
|
|
82
112
|
}
|
|
83
113
|
|
|
@@ -85,6 +115,61 @@ public class KeyboardMovementObserver: NSObject {
|
|
|
85
115
|
var data = [AnyHashable: Any]()
|
|
86
116
|
data["height"] = 0
|
|
87
117
|
|
|
118
|
+
onEvent("onKeyboardMoveEnd", 0 as NSNumber, 0)
|
|
88
119
|
onNotify("KeyboardController::keyboardDidHide", data)
|
|
120
|
+
|
|
121
|
+
removeKeyboardWatcher()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@objc func setupKeyboardWatcher() {
|
|
125
|
+
displayLink = CADisplayLink(target: self, selector: #selector(updateKeyboardFrame))
|
|
126
|
+
displayLink?.preferredFramesPerSecond = 120 // will fallback to 60 fps for devices without Pro Motion display
|
|
127
|
+
displayLink?.add(to: .main, forMode: .common)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@objc func removeKeyboardWatcher() {
|
|
131
|
+
displayLink?.invalidate()
|
|
132
|
+
displayLink = nil
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// https://stackoverflow.com/questions/32598490/show-uiview-with-buttons-over-keyboard-like-in-skype-viber-messengers-swift-i
|
|
136
|
+
func findKeyboardView() -> UIView? {
|
|
137
|
+
var result: UIView?
|
|
138
|
+
|
|
139
|
+
let windows = UIApplication.shared.windows
|
|
140
|
+
for window in windows {
|
|
141
|
+
if window.description.hasPrefix("<UITextEffectsWindow") {
|
|
142
|
+
for subview in window.subviews {
|
|
143
|
+
if subview.description.hasPrefix("<UIInputSetContainerView") {
|
|
144
|
+
for hostView in subview.subviews {
|
|
145
|
+
if hostView.description.hasPrefix("<UIInputSetHostView") {
|
|
146
|
+
result = hostView as? UIView
|
|
147
|
+
break
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
break
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return result
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@objc func updateKeyboardFrame() {
|
|
160
|
+
if keyboardView == nil {
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var keyboardFrameY = keyboardView!.layer.presentation()!.frame.origin.y
|
|
165
|
+
var keyboardWindowH = keyboardView!.window!.bounds.size.height
|
|
166
|
+
var keyboardPosition = keyboardWindowH - keyboardFrameY
|
|
167
|
+
|
|
168
|
+
if keyboardPosition == prevKeyboardPosition || keyboardFrameY == 0 {
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
prevKeyboardPosition = keyboardPosition
|
|
173
|
+
onEvent("onKeyboardMove", keyboardPosition as NSNumber, keyboardPosition / CGFloat(keyboardHeight) as NSNumber)
|
|
89
174
|
}
|
|
90
175
|
}
|
package/lib/commonjs/animated.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.styles = exports.KeyboardProvider = void 0;
|
|
7
7
|
|
|
8
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
9
|
|
|
@@ -11,6 +11,10 @@ var _reactNative = require("react-native");
|
|
|
11
11
|
|
|
12
12
|
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
13
13
|
|
|
14
|
+
var _context = require("./context");
|
|
15
|
+
|
|
16
|
+
var _internal = require("./internal");
|
|
17
|
+
|
|
14
18
|
var _native = require("./native");
|
|
15
19
|
|
|
16
20
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -19,59 +23,6 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
19
23
|
|
|
20
24
|
const KeyboardControllerViewAnimated = _reactNativeReanimated.default.createAnimatedComponent(_reactNative.Animated.createAnimatedComponent(_native.KeyboardControllerView));
|
|
21
25
|
|
|
22
|
-
const defaultContext = {
|
|
23
|
-
animated: {
|
|
24
|
-
progress: new _reactNative.Animated.Value(0),
|
|
25
|
-
height: new _reactNative.Animated.Value(0)
|
|
26
|
-
},
|
|
27
|
-
reanimated: {
|
|
28
|
-
progress: {
|
|
29
|
-
value: 0
|
|
30
|
-
},
|
|
31
|
-
height: {
|
|
32
|
-
value: 0
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const KeyboardContext = /*#__PURE__*/_react.default.createContext(defaultContext);
|
|
38
|
-
|
|
39
|
-
exports.KeyboardContext = KeyboardContext;
|
|
40
|
-
|
|
41
|
-
const useKeyboardAnimation = () => {
|
|
42
|
-
(0, _native.useResizeMode)();
|
|
43
|
-
const context = (0, _react.useContext)(KeyboardContext);
|
|
44
|
-
return context.animated;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
exports.useKeyboardAnimation = useKeyboardAnimation;
|
|
48
|
-
|
|
49
|
-
const useReanimatedKeyboardAnimation = () => {
|
|
50
|
-
(0, _native.useResizeMode)();
|
|
51
|
-
const context = (0, _react.useContext)(KeyboardContext);
|
|
52
|
-
return context.reanimated;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
exports.useReanimatedKeyboardAnimation = useReanimatedKeyboardAnimation;
|
|
56
|
-
|
|
57
|
-
function useAnimatedKeyboardHandler(handlers, dependencies) {
|
|
58
|
-
const {
|
|
59
|
-
context,
|
|
60
|
-
doDependenciesDiffer
|
|
61
|
-
} = (0, _reactNativeReanimated.useHandler)(handlers, dependencies);
|
|
62
|
-
return (0, _reactNativeReanimated.useEvent)(event => {
|
|
63
|
-
'worklet';
|
|
64
|
-
|
|
65
|
-
const {
|
|
66
|
-
onKeyboardMove
|
|
67
|
-
} = handlers;
|
|
68
|
-
|
|
69
|
-
if (onKeyboardMove && event.eventName.endsWith('onKeyboardMove')) {
|
|
70
|
-
onKeyboardMove(event, context);
|
|
71
|
-
}
|
|
72
|
-
}, ['onKeyboardMove'], doDependenciesDiffer);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
26
|
const styles = _reactNative.StyleSheet.create({
|
|
76
27
|
container: {
|
|
77
28
|
flex: 1
|
|
@@ -89,19 +40,27 @@ const KeyboardProvider = _ref => {
|
|
|
89
40
|
children,
|
|
90
41
|
statusBarTranslucent
|
|
91
42
|
} = _ref;
|
|
43
|
+
// animated values
|
|
92
44
|
const progress = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
93
|
-
const height = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
45
|
+
const height = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current; // shared values
|
|
46
|
+
|
|
94
47
|
const progressSV = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
95
48
|
const heightSV = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
49
|
+
const {
|
|
50
|
+
setHandlers,
|
|
51
|
+
broadcast
|
|
52
|
+
} = (0, _internal.useSharedHandlers)(); // memo
|
|
53
|
+
|
|
96
54
|
const context = (0, _react.useMemo)(() => ({
|
|
97
55
|
animated: {
|
|
98
56
|
progress: progress,
|
|
99
|
-
height: height
|
|
57
|
+
height: _reactNative.Animated.multiply(height, -1)
|
|
100
58
|
},
|
|
101
59
|
reanimated: {
|
|
102
60
|
progress: progressSV,
|
|
103
61
|
height: heightSV
|
|
104
|
-
}
|
|
62
|
+
},
|
|
63
|
+
setHandlers
|
|
105
64
|
}), []);
|
|
106
65
|
const style = (0, _react.useMemo)(() => [styles.hidden, {
|
|
107
66
|
transform: [{
|
|
@@ -117,20 +76,42 @@ const KeyboardProvider = _ref => {
|
|
|
117
76
|
}
|
|
118
77
|
}], {
|
|
119
78
|
useNativeDriver: true
|
|
120
|
-
}), []);
|
|
121
|
-
|
|
79
|
+
}), []); // handlers
|
|
80
|
+
|
|
81
|
+
const updateSharedValues = (event, platforms) => {
|
|
82
|
+
'worklet';
|
|
83
|
+
|
|
84
|
+
if (platforms.includes(_reactNative.Platform.OS)) {
|
|
85
|
+
progressSV.value = event.progress;
|
|
86
|
+
heightSV.value = -event.height;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const handler = (0, _internal.useAnimatedKeyboardHandler)({
|
|
91
|
+
onKeyboardMoveStart: event => {
|
|
92
|
+
'worklet';
|
|
93
|
+
|
|
94
|
+
broadcast('onStart', event);
|
|
95
|
+
updateSharedValues(event, ['ios']);
|
|
96
|
+
},
|
|
122
97
|
onKeyboardMove: event => {
|
|
123
98
|
'worklet';
|
|
124
99
|
|
|
125
|
-
|
|
126
|
-
|
|
100
|
+
broadcast('onMove', event);
|
|
101
|
+
updateSharedValues(event, ['android']);
|
|
102
|
+
},
|
|
103
|
+
onKeyboardMoveEnd: event => {
|
|
104
|
+
'worklet';
|
|
105
|
+
|
|
106
|
+
broadcast('onEnd', event);
|
|
127
107
|
}
|
|
128
108
|
}, []);
|
|
129
|
-
return /*#__PURE__*/_react.default.createElement(KeyboardContext.Provider, {
|
|
109
|
+
return /*#__PURE__*/_react.default.createElement(_context.KeyboardContext.Provider, {
|
|
130
110
|
value: context
|
|
131
111
|
}, /*#__PURE__*/_react.default.createElement(KeyboardControllerViewAnimated, {
|
|
132
112
|
onKeyboardMoveReanimated: handler,
|
|
133
|
-
onKeyboardMove:
|
|
113
|
+
onKeyboardMoveStart: _reactNative.Platform.OS === 'ios' ? onKeyboardMove : undefined,
|
|
114
|
+
onKeyboardMove: _reactNative.Platform.OS === 'android' ? onKeyboardMove : undefined,
|
|
134
115
|
statusBarTranslucent: statusBarTranslucent,
|
|
135
116
|
style: styles.container
|
|
136
117
|
}, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
|