react-native-keyboard-controller 1.14.0 → 1.14.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/android/src/main/java/com/reactnativekeyboardcontroller/constants/Keyboard.kt +7 -0
- package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +29 -10
- package/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt +32 -4
- package/android/src/main/java/com/reactnativekeyboardcontroller/modules/StatusBarManagerCompatModuleImpl.kt +7 -2
- package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +5 -1
- package/ios/{core → animations}/KeyboardAnimation.swift +1 -0
- package/ios/{core → animations}/SpringAnimation.swift +1 -1
- package/ios/{core → animations}/TimingAnimation.swift +21 -20
- package/ios/extensions/UIApplication.swift +16 -0
- package/ios/extensions/UIWindow.swift +1 -1
- package/lib/commonjs/components/KeyboardAvoidingView/hooks.js +6 -0
- package/lib/commonjs/components/KeyboardAvoidingView/hooks.js.map +1 -1
- package/lib/module/components/KeyboardAvoidingView/hooks.js +6 -0
- package/lib/module/components/KeyboardAvoidingView/hooks.js.map +1 -1
- package/package.json +1 -1
- package/src/components/KeyboardAvoidingView/hooks.ts +6 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
package com.reactnativekeyboardcontroller.listeners
|
|
2
2
|
|
|
3
|
-
import android.os.Build
|
|
4
3
|
import android.view.View
|
|
5
4
|
import android.view.ViewTreeObserver.OnGlobalFocusChangeListener
|
|
6
5
|
import androidx.core.graphics.Insets
|
|
@@ -14,6 +13,7 @@ import com.facebook.react.uimanager.ThemedReactContext
|
|
|
14
13
|
import com.facebook.react.uimanager.UIManagerHelper
|
|
15
14
|
import com.facebook.react.views.textinput.ReactEditText
|
|
16
15
|
import com.facebook.react.views.view.ReactViewGroup
|
|
16
|
+
import com.reactnativekeyboardcontroller.constants.Keyboard
|
|
17
17
|
import com.reactnativekeyboardcontroller.events.KeyboardTransitionEvent
|
|
18
18
|
import com.reactnativekeyboardcontroller.extensions.dispatchEvent
|
|
19
19
|
import com.reactnativekeyboardcontroller.extensions.dp
|
|
@@ -24,7 +24,7 @@ import com.reactnativekeyboardcontroller.log.Logger
|
|
|
24
24
|
import kotlin.math.abs
|
|
25
25
|
|
|
26
26
|
private val TAG = KeyboardAnimationCallback::class.qualifiedName
|
|
27
|
-
private val isResizeHandledInCallbackMethods =
|
|
27
|
+
private val isResizeHandledInCallbackMethods = Keyboard.IS_ANIMATION_EMULATED
|
|
28
28
|
|
|
29
29
|
data class KeyboardAnimationCallbackConfig(
|
|
30
30
|
val persistentInsetTypes: Int,
|
|
@@ -33,13 +33,22 @@ data class KeyboardAnimationCallbackConfig(
|
|
|
33
33
|
val hasTranslucentNavigationBar: Boolean = false,
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
+
interface Suspendable {
|
|
37
|
+
var isSuspended: Boolean
|
|
38
|
+
|
|
39
|
+
fun suspend(suspended: Boolean) {
|
|
40
|
+
isSuspended = suspended
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
class KeyboardAnimationCallback(
|
|
37
45
|
val eventPropagationView: ReactViewGroup,
|
|
38
46
|
val view: View,
|
|
39
47
|
val context: ThemedReactContext?,
|
|
40
48
|
private val config: KeyboardAnimationCallbackConfig,
|
|
41
49
|
) : WindowInsetsAnimationCompat.Callback(config.dispatchMode),
|
|
42
|
-
OnApplyWindowInsetsListener
|
|
50
|
+
OnApplyWindowInsetsListener,
|
|
51
|
+
Suspendable {
|
|
43
52
|
private val surfaceId = UIManagerHelper.getSurfaceId(eventPropagationView)
|
|
44
53
|
|
|
45
54
|
// state variables
|
|
@@ -50,6 +59,7 @@ class KeyboardAnimationCallback(
|
|
|
50
59
|
private var duration = 0
|
|
51
60
|
private var viewTagFocused = -1
|
|
52
61
|
private var animationsToSkip = hashSetOf<WindowInsetsAnimationCompat>()
|
|
62
|
+
override var isSuspended: Boolean = false
|
|
53
63
|
|
|
54
64
|
// listeners
|
|
55
65
|
private val focusListener =
|
|
@@ -147,7 +157,7 @@ class KeyboardAnimationCallback(
|
|
|
147
157
|
this.onKeyboardResized(keyboardHeight)
|
|
148
158
|
}
|
|
149
159
|
|
|
150
|
-
return
|
|
160
|
+
return insets
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
@Suppress("detekt:ReturnCount")
|
|
@@ -155,7 +165,7 @@ class KeyboardAnimationCallback(
|
|
|
155
165
|
animation: WindowInsetsAnimationCompat,
|
|
156
166
|
bounds: WindowInsetsAnimationCompat.BoundsCompat,
|
|
157
167
|
): WindowInsetsAnimationCompat.BoundsCompat {
|
|
158
|
-
if (!animation.isKeyboardAnimation) {
|
|
168
|
+
if (!animation.isKeyboardAnimation || isSuspended) {
|
|
159
169
|
return bounds
|
|
160
170
|
}
|
|
161
171
|
|
|
@@ -211,7 +221,13 @@ class KeyboardAnimationCallback(
|
|
|
211
221
|
// onProgress() is called when any of the running animations progress...
|
|
212
222
|
|
|
213
223
|
// ignore non-keyboard animation or animation that we intentionally want to skip
|
|
214
|
-
|
|
224
|
+
val shouldSkipAnimation =
|
|
225
|
+
runningAnimations.find {
|
|
226
|
+
it.isKeyboardAnimation && !animationsToSkip.contains(it)
|
|
227
|
+
} == null
|
|
228
|
+
if (isSuspended || shouldSkipAnimation) {
|
|
229
|
+
return insets
|
|
230
|
+
}
|
|
215
231
|
|
|
216
232
|
// First we get the insets which are potentially deferred
|
|
217
233
|
val typesInset = insets.getInsets(config.deferredInsetTypes)
|
|
@@ -262,7 +278,7 @@ class KeyboardAnimationCallback(
|
|
|
262
278
|
override fun onEnd(animation: WindowInsetsAnimationCompat) {
|
|
263
279
|
super.onEnd(animation)
|
|
264
280
|
|
|
265
|
-
if (!animation.isKeyboardAnimation) {
|
|
281
|
+
if (!animation.isKeyboardAnimation || isSuspended) {
|
|
266
282
|
return
|
|
267
283
|
}
|
|
268
284
|
|
|
@@ -311,10 +327,13 @@ class KeyboardAnimationCallback(
|
|
|
311
327
|
duration = 0
|
|
312
328
|
}
|
|
313
329
|
|
|
314
|
-
fun syncKeyboardPosition(
|
|
315
|
-
|
|
330
|
+
fun syncKeyboardPosition(
|
|
331
|
+
height: Double? = null,
|
|
332
|
+
isVisible: Boolean? = null,
|
|
333
|
+
) {
|
|
334
|
+
val keyboardHeight = height ?: getCurrentKeyboardHeight()
|
|
316
335
|
// update internal state
|
|
317
|
-
isKeyboardVisible = isKeyboardVisible()
|
|
336
|
+
isKeyboardVisible = isVisible ?: isKeyboardVisible()
|
|
318
337
|
prevKeyboardHeight = keyboardHeight
|
|
319
338
|
isTransitioning = false
|
|
320
339
|
duration = 0
|
package/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.reactnativekeyboardcontroller.modal
|
|
2
2
|
|
|
3
|
+
import android.view.ViewGroup
|
|
3
4
|
import android.view.WindowManager
|
|
4
5
|
import androidx.core.view.ViewCompat
|
|
5
6
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
@@ -10,16 +11,20 @@ import com.facebook.react.uimanager.events.EventDispatcherListener
|
|
|
10
11
|
import com.facebook.react.views.modal.ReactModalHostView
|
|
11
12
|
import com.facebook.react.views.view.ReactViewGroup
|
|
12
13
|
import com.reactnativekeyboardcontroller.BuildConfig
|
|
14
|
+
import com.reactnativekeyboardcontroller.constants.Keyboard
|
|
15
|
+
import com.reactnativekeyboardcontroller.extensions.removeSelf
|
|
13
16
|
import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallback
|
|
14
17
|
import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallbackConfig
|
|
15
18
|
import com.reactnativekeyboardcontroller.log.Logger
|
|
16
19
|
|
|
17
20
|
private val TAG = ModalAttachedWatcher::class.qualifiedName
|
|
21
|
+
private val areEventsComingFromOwnWindow = !Keyboard.IS_ANIMATION_EMULATED
|
|
18
22
|
|
|
19
23
|
class ModalAttachedWatcher(
|
|
20
24
|
private val view: ReactViewGroup,
|
|
21
25
|
private val reactContext: ThemedReactContext,
|
|
22
26
|
private val config: () -> KeyboardAnimationCallbackConfig,
|
|
27
|
+
private var callback: () -> KeyboardAnimationCallback?,
|
|
23
28
|
) : EventDispatcherListener {
|
|
24
29
|
private val archType = if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) UIManagerType.FABRIC else UIManagerType.DEFAULT
|
|
25
30
|
private val uiManager = UIManagerHelper.getUIManager(reactContext.reactApplicationContext, archType)
|
|
@@ -44,9 +49,13 @@ class ModalAttachedWatcher(
|
|
|
44
49
|
|
|
45
50
|
val dialog = modal.dialog
|
|
46
51
|
val window = dialog?.window
|
|
47
|
-
val rootView = window?.decorView?.rootView
|
|
52
|
+
val rootView = window?.decorView?.rootView as ViewGroup?
|
|
48
53
|
|
|
49
54
|
if (rootView != null) {
|
|
55
|
+
val eventView =
|
|
56
|
+
ReactViewGroup(reactContext).apply {
|
|
57
|
+
layoutParams = ViewGroup.LayoutParams(0, 0)
|
|
58
|
+
}
|
|
50
59
|
val callback =
|
|
51
60
|
KeyboardAnimationCallback(
|
|
52
61
|
view = rootView,
|
|
@@ -55,16 +64,35 @@ class ModalAttachedWatcher(
|
|
|
55
64
|
config = config(),
|
|
56
65
|
)
|
|
57
66
|
|
|
67
|
+
rootView.addView(eventView)
|
|
68
|
+
// on Android < 12 all events for `WindowInsetsAnimationCallback`
|
|
69
|
+
// go through main `rootView`, so we don't need to stop main
|
|
70
|
+
// callback - otherwise keyboard transitions will not be animated
|
|
71
|
+
this.callback()?.suspend(areEventsComingFromOwnWindow)
|
|
58
72
|
ViewCompat.setWindowInsetsAnimationCallback(rootView, callback)
|
|
59
|
-
ViewCompat.setOnApplyWindowInsetsListener(
|
|
73
|
+
ViewCompat.setOnApplyWindowInsetsListener(eventView, callback)
|
|
60
74
|
|
|
61
|
-
|
|
75
|
+
if (areEventsComingFromOwnWindow) {
|
|
76
|
+
// when modal is shown then keyboard will be hidden by default
|
|
77
|
+
//
|
|
78
|
+
// - if events are coming from main window - then keyboard position
|
|
79
|
+
// will be synchronized from main window callback
|
|
80
|
+
// - if events are coming from modal window - then we need to update
|
|
81
|
+
// position ourself, because callback can be attached after keyboard
|
|
82
|
+
// auto-dismissal and we may miss some events and keyboard position
|
|
83
|
+
// will be outdated
|
|
84
|
+
callback.syncKeyboardPosition(0.0, false)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
dialog?.setOnDismissListener {
|
|
62
88
|
callback.syncKeyboardPosition()
|
|
63
89
|
callback.destroy()
|
|
90
|
+
eventView.removeSelf()
|
|
91
|
+
this.callback()?.suspend(false)
|
|
64
92
|
}
|
|
65
93
|
|
|
66
94
|
// imitating edge-to-edge mode behavior
|
|
67
|
-
window
|
|
95
|
+
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
|
|
68
96
|
}
|
|
69
97
|
}
|
|
70
98
|
|
|
@@ -2,6 +2,7 @@ package com.reactnativekeyboardcontroller.modules
|
|
|
2
2
|
|
|
3
3
|
import android.animation.ArgbEvaluator
|
|
4
4
|
import android.animation.ValueAnimator
|
|
5
|
+
import android.app.Activity
|
|
5
6
|
import android.os.Build
|
|
6
7
|
import androidx.annotation.RequiresApi
|
|
7
8
|
import androidx.core.view.WindowInsetsCompat
|
|
@@ -11,6 +12,7 @@ import com.facebook.react.bridge.UiThreadUtil
|
|
|
11
12
|
import com.reactnativekeyboardcontroller.extensions.rootView
|
|
12
13
|
import com.reactnativekeyboardcontroller.log.Logger
|
|
13
14
|
import com.reactnativekeyboardcontroller.views.EdgeToEdgeReactViewGroup
|
|
15
|
+
import java.lang.ref.WeakReference
|
|
14
16
|
|
|
15
17
|
private val TAG = StatusBarManagerCompatModuleImpl::class.qualifiedName
|
|
16
18
|
|
|
@@ -18,6 +20,7 @@ class StatusBarManagerCompatModuleImpl(
|
|
|
18
20
|
private val mReactContext: ReactApplicationContext,
|
|
19
21
|
) {
|
|
20
22
|
private var controller: WindowInsetsControllerCompat? = null
|
|
23
|
+
private var lastActivity = WeakReference<Activity?>(null)
|
|
21
24
|
|
|
22
25
|
fun setHidden(hidden: Boolean) {
|
|
23
26
|
UiThreadUtil.runOnUiThread {
|
|
@@ -71,8 +74,9 @@ class StatusBarManagerCompatModuleImpl(
|
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
private fun getController(): WindowInsetsControllerCompat? {
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
val activity = mReactContext.currentActivity
|
|
78
|
+
|
|
79
|
+
if (this.controller == null || activity != lastActivity.get()) {
|
|
76
80
|
if (activity == null) {
|
|
77
81
|
Logger.w(
|
|
78
82
|
TAG,
|
|
@@ -82,6 +86,7 @@ class StatusBarManagerCompatModuleImpl(
|
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
val window = activity.window
|
|
89
|
+
lastActivity = WeakReference(activity)
|
|
85
90
|
|
|
86
91
|
this.controller = WindowInsetsControllerCompat(window, window.decorView)
|
|
87
92
|
}
|
package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt
CHANGED
|
@@ -47,7 +47,7 @@ class EdgeToEdgeReactViewGroup(
|
|
|
47
47
|
)
|
|
48
48
|
|
|
49
49
|
// managers/watchers
|
|
50
|
-
private val modalAttachedWatcher = ModalAttachedWatcher(this, reactContext, ::config)
|
|
50
|
+
private val modalAttachedWatcher = ModalAttachedWatcher(this, reactContext, ::config, ::getKeyboardCallback)
|
|
51
51
|
|
|
52
52
|
init {
|
|
53
53
|
reactContext.setupWindowDimensionsListener()
|
|
@@ -195,6 +195,10 @@ class EdgeToEdgeReactViewGroup(
|
|
|
195
195
|
}
|
|
196
196
|
// endregion
|
|
197
197
|
|
|
198
|
+
// region Helpers
|
|
199
|
+
private fun getKeyboardCallback(): KeyboardAnimationCallback? = this.callback
|
|
200
|
+
// endregion
|
|
201
|
+
|
|
198
202
|
// region Props setters
|
|
199
203
|
fun setStatusBarTranslucent(isStatusBarTranslucent: Boolean) {
|
|
200
204
|
this.isStatusBarTranslucent = isStatusBarTranslucent
|
|
@@ -10,7 +10,7 @@ import Foundation
|
|
|
10
10
|
import QuartzCore
|
|
11
11
|
|
|
12
12
|
// swiftlint:disable identifier_name
|
|
13
|
-
public class SpringAnimation: KeyboardAnimation {
|
|
13
|
+
public final class SpringAnimation: KeyboardAnimation {
|
|
14
14
|
// internal variables
|
|
15
15
|
private let zeta: Double // Damping ratio
|
|
16
16
|
private let omega0: Double // Undamped angular frequency of the oscillator
|
|
@@ -15,13 +15,13 @@ import QuartzCore
|
|
|
15
15
|
* This class calculates the progress of animations based on Bézier curve control points.
|
|
16
16
|
* For more details on the Bézier curves, see [Desmos Graph](https://www.desmos.com/calculator/eynenh1aga?lang=en).
|
|
17
17
|
*/
|
|
18
|
-
public class TimingAnimation: KeyboardAnimation {
|
|
18
|
+
public final class TimingAnimation: KeyboardAnimation {
|
|
19
19
|
private let p1: CGPoint
|
|
20
20
|
private let p2: CGPoint
|
|
21
21
|
|
|
22
22
|
init(animation: CABasicAnimation, fromValue: Double, toValue: Double) {
|
|
23
23
|
let timingFunction = animation.timingFunction
|
|
24
|
-
var controlPoints:
|
|
24
|
+
var controlPoints: ContiguousArray<Float> = ContiguousArray([0, 0, 0, 0])
|
|
25
25
|
timingFunction?.getControlPoint(at: 1, values: &controlPoints[0])
|
|
26
26
|
timingFunction?.getControlPoint(at: 2, values: &controlPoints[2])
|
|
27
27
|
let p1 = CGPoint(x: CGFloat(controlPoints[0]), y: CGFloat(controlPoints[1]))
|
|
@@ -33,7 +33,20 @@ public class TimingAnimation: KeyboardAnimation {
|
|
|
33
33
|
super.init(fromValue: fromValue, toValue: toValue, animation: animation)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
// public functions
|
|
37
|
+
override func valueAt(time: Double) -> Double {
|
|
38
|
+
let x = time * Double(speed)
|
|
39
|
+
let frames = (animation?.duration ?? 0.0) * Double(speed)
|
|
40
|
+
let fraction = min(x / frames, 1)
|
|
41
|
+
let t = findTForX(xTarget: fraction)
|
|
42
|
+
|
|
43
|
+
let progress = bezierY(t: t)
|
|
44
|
+
|
|
45
|
+
return fromValue + (toValue - fromValue) * CGFloat(progress)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// private functions
|
|
49
|
+
private func bezier(t: CGFloat, valueForPoint: (CGPoint) -> CGFloat) -> CGFloat {
|
|
37
50
|
let u = 1 - t
|
|
38
51
|
let tt = t * t
|
|
39
52
|
let uu = u * u
|
|
@@ -49,27 +62,15 @@ public class TimingAnimation: KeyboardAnimation {
|
|
|
49
62
|
return term1 + term2 + term3
|
|
50
63
|
}
|
|
51
64
|
|
|
52
|
-
func bezierY(t: CGFloat) -> CGFloat {
|
|
65
|
+
private func bezierY(t: CGFloat) -> CGFloat {
|
|
53
66
|
return bezier(t: t) { $0.y }
|
|
54
67
|
}
|
|
55
68
|
|
|
56
|
-
func bezierX(t: CGFloat) -> CGFloat {
|
|
69
|
+
private func bezierX(t: CGFloat) -> CGFloat {
|
|
57
70
|
return bezier(t: t) { $0.x }
|
|
58
71
|
}
|
|
59
72
|
|
|
60
|
-
|
|
61
|
-
override func valueAt(time: Double) -> Double {
|
|
62
|
-
let x = time * Double(speed)
|
|
63
|
-
let frames = (animation?.duration ?? 0.0) * Double(speed)
|
|
64
|
-
let fraction = min(x / frames, 1)
|
|
65
|
-
let t = findTForX(xTarget: fraction)
|
|
66
|
-
|
|
67
|
-
let progress = bezierY(t: t)
|
|
68
|
-
|
|
69
|
-
return fromValue + (toValue - fromValue) * CGFloat(progress)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
func findTForX(xTarget: CGFloat, epsilon: CGFloat = 0.0001, maxIterations: Int = 100) -> CGFloat {
|
|
73
|
+
private func findTForX(xTarget: CGFloat, epsilon: CGFloat = 0.0001, maxIterations: Int = 100) -> CGFloat {
|
|
73
74
|
var t: CGFloat = 0.5 // Start with an initial guess of t = 0.5
|
|
74
75
|
for _ in 0 ..< maxIterations {
|
|
75
76
|
let currentX = bezierX(t: t) // Compute the x-coordinate at t
|
|
@@ -84,7 +85,7 @@ public class TimingAnimation: KeyboardAnimation {
|
|
|
84
85
|
return t // Return the approximation of t
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
func bezierDerivative(t: CGFloat, valueForPoint: (CGPoint) -> CGFloat) -> CGFloat {
|
|
88
|
+
private func bezierDerivative(t: CGFloat, valueForPoint: (CGPoint) -> CGFloat) -> CGFloat {
|
|
88
89
|
let u = 1 - t
|
|
89
90
|
let uu = u * u
|
|
90
91
|
let tt = t * t
|
|
@@ -100,7 +101,7 @@ public class TimingAnimation: KeyboardAnimation {
|
|
|
100
101
|
return term1 + term2 + term3
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
func bezierXDerivative(t: CGFloat) -> CGFloat {
|
|
104
|
+
private func bezierXDerivative(t: CGFloat) -> CGFloat {
|
|
104
105
|
return bezierDerivative(t: t) { $0.x }
|
|
105
106
|
}
|
|
106
107
|
}
|
|
@@ -9,6 +9,22 @@ import Foundation
|
|
|
9
9
|
import UIKit
|
|
10
10
|
|
|
11
11
|
public extension UIApplication {
|
|
12
|
+
var activeWindow: UIWindow? {
|
|
13
|
+
if #available(iOS 13.0, *) {
|
|
14
|
+
for scene in connectedScenes {
|
|
15
|
+
if scene.activationState == .foregroundActive,
|
|
16
|
+
let windowScene = scene as? UIWindowScene,
|
|
17
|
+
let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow })
|
|
18
|
+
{
|
|
19
|
+
return keyWindow
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return nil
|
|
23
|
+
} else {
|
|
24
|
+
return windows.last { $0.isKeyWindow }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
12
28
|
static func topViewController(
|
|
13
29
|
base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController
|
|
14
30
|
) -> UIViewController? {
|
|
@@ -38,7 +38,7 @@ public extension UIWindow {
|
|
|
38
38
|
|
|
39
39
|
func getTopWindow() -> UIWindow? {
|
|
40
40
|
// Return the keyboard window if it's available, otherwise return the last window
|
|
41
|
-
return keyboardWindow ?? UIApplication.shared.
|
|
41
|
+
return keyboardWindow ?? UIApplication.shared.activeWindow
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNativeReanimated","require","_context","_hooks","useKeyboardAnimation","reanimated","useKeyboardContext","heightWhenOpened","useSharedValue","height","value","progress","isClosed","useKeyboardHandler","onStart","e","onMove","onEnd","exports"],"sources":["hooks.ts"],"sourcesContent":["import { useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardContext } from \"../../context\";\nimport { useKeyboardHandler } from \"../../hooks\";\n\nexport const useKeyboardAnimation = () => {\n const { reanimated } = useKeyboardContext();\n const heightWhenOpened = useSharedValue(-reanimated.height.value);\n const height = useSharedValue(-reanimated.height.value);\n const progress = useSharedValue(reanimated.progress.value);\n const isClosed = useSharedValue(reanimated.progress.value === 0);\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n isClosed.value = false;\n heightWhenOpened.value = e.height;\n }\n },\n onMove: (e) => {\n \"worklet\";\n\n progress.value = e.progress;\n height.value = e.height;\n },\n onEnd: (e) => {\n \"worklet\";\n\n isClosed.value = e.height === 0;\n\n height.value = e.height;\n progress.value = e.progress;\n },\n },\n [],\n );\n\n return { height, progress, heightWhenOpened, isClosed };\n};\n"],"mappings":";;;;;;AAAA,IAAAA,sBAAA,GAAAC,OAAA;AAEA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAEO,MAAMG,oBAAoB,GAAGA,CAAA,KAAM;EACxC,MAAM;IAAEC;EAAW,CAAC,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAC3C,MAAMC,gBAAgB,GAAG,IAAAC,qCAAc,EAAC,CAACH,UAAU,CAACI,MAAM,CAACC,KAAK,CAAC;EACjE,MAAMD,MAAM,GAAG,IAAAD,qCAAc,EAAC,CAACH,UAAU,CAACI,MAAM,CAACC,KAAK,CAAC;EACvD,MAAMC,QAAQ,GAAG,IAAAH,qCAAc,EAACH,UAAU,CAACM,QAAQ,CAACD,KAAK,CAAC;EAC1D,MAAME,QAAQ,GAAG,IAAAJ,qCAAc,EAACH,UAAU,CAACM,QAAQ,CAACD,KAAK,KAAK,CAAC,CAAC;EAEhE,IAAAG,yBAAkB,EAChB;IACEC,OAAO,EAAGC,CAAC,IAAK;MACd,SAAS;;MAET,IAAIA,CAAC,CAACN,MAAM,GAAG,CAAC,EAAE;QAChB;QACAG,QAAQ,CAACF,KAAK,GAAG,KAAK;QACtBH,gBAAgB,CAACG,KAAK,GAAGK,CAAC,CAACN,MAAM;MACnC;IACF,CAAC;IACDO,MAAM,EAAGD,CAAC,IAAK;MACb,SAAS;;MAETJ,QAAQ,CAACD,KAAK,GAAGK,CAAC,CAACJ,QAAQ;MAC3BF,MAAM,CAACC,KAAK,GAAGK,CAAC,CAACN,MAAM;IACzB,CAAC;IACDQ,
|
|
1
|
+
{"version":3,"names":["_reactNativeReanimated","require","_context","_hooks","useKeyboardAnimation","reanimated","useKeyboardContext","heightWhenOpened","useSharedValue","height","value","progress","isClosed","useKeyboardHandler","onStart","e","onMove","onInteractive","onEnd","exports"],"sources":["hooks.ts"],"sourcesContent":["import { useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardContext } from \"../../context\";\nimport { useKeyboardHandler } from \"../../hooks\";\n\nexport const useKeyboardAnimation = () => {\n const { reanimated } = useKeyboardContext();\n const heightWhenOpened = useSharedValue(-reanimated.height.value);\n const height = useSharedValue(-reanimated.height.value);\n const progress = useSharedValue(reanimated.progress.value);\n const isClosed = useSharedValue(reanimated.progress.value === 0);\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n isClosed.value = false;\n heightWhenOpened.value = e.height;\n }\n },\n onMove: (e) => {\n \"worklet\";\n\n progress.value = e.progress;\n height.value = e.height;\n },\n onInteractive: (e) => {\n \"worklet\";\n\n progress.value = e.progress;\n height.value = e.height;\n },\n onEnd: (e) => {\n \"worklet\";\n\n isClosed.value = e.height === 0;\n\n height.value = e.height;\n progress.value = e.progress;\n },\n },\n [],\n );\n\n return { height, progress, heightWhenOpened, isClosed };\n};\n"],"mappings":";;;;;;AAAA,IAAAA,sBAAA,GAAAC,OAAA;AAEA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAEO,MAAMG,oBAAoB,GAAGA,CAAA,KAAM;EACxC,MAAM;IAAEC;EAAW,CAAC,GAAG,IAAAC,2BAAkB,EAAC,CAAC;EAC3C,MAAMC,gBAAgB,GAAG,IAAAC,qCAAc,EAAC,CAACH,UAAU,CAACI,MAAM,CAACC,KAAK,CAAC;EACjE,MAAMD,MAAM,GAAG,IAAAD,qCAAc,EAAC,CAACH,UAAU,CAACI,MAAM,CAACC,KAAK,CAAC;EACvD,MAAMC,QAAQ,GAAG,IAAAH,qCAAc,EAACH,UAAU,CAACM,QAAQ,CAACD,KAAK,CAAC;EAC1D,MAAME,QAAQ,GAAG,IAAAJ,qCAAc,EAACH,UAAU,CAACM,QAAQ,CAACD,KAAK,KAAK,CAAC,CAAC;EAEhE,IAAAG,yBAAkB,EAChB;IACEC,OAAO,EAAGC,CAAC,IAAK;MACd,SAAS;;MAET,IAAIA,CAAC,CAACN,MAAM,GAAG,CAAC,EAAE;QAChB;QACAG,QAAQ,CAACF,KAAK,GAAG,KAAK;QACtBH,gBAAgB,CAACG,KAAK,GAAGK,CAAC,CAACN,MAAM;MACnC;IACF,CAAC;IACDO,MAAM,EAAGD,CAAC,IAAK;MACb,SAAS;;MAETJ,QAAQ,CAACD,KAAK,GAAGK,CAAC,CAACJ,QAAQ;MAC3BF,MAAM,CAACC,KAAK,GAAGK,CAAC,CAACN,MAAM;IACzB,CAAC;IACDQ,aAAa,EAAGF,CAAC,IAAK;MACpB,SAAS;;MAETJ,QAAQ,CAACD,KAAK,GAAGK,CAAC,CAACJ,QAAQ;MAC3BF,MAAM,CAACC,KAAK,GAAGK,CAAC,CAACN,MAAM;IACzB,CAAC;IACDS,KAAK,EAAGH,CAAC,IAAK;MACZ,SAAS;;MAETH,QAAQ,CAACF,KAAK,GAAGK,CAAC,CAACN,MAAM,KAAK,CAAC;MAE/BA,MAAM,CAACC,KAAK,GAAGK,CAAC,CAACN,MAAM;MACvBE,QAAQ,CAACD,KAAK,GAAGK,CAAC,CAACJ,QAAQ;IAC7B;EACF,CAAC,EACD,EACF,CAAC;EAED,OAAO;IAAEF,MAAM;IAAEE,QAAQ;IAAEJ,gBAAgB;IAAEK;EAAS,CAAC;AACzD,CAAC;AAACO,OAAA,CAAAf,oBAAA,GAAAA,oBAAA","ignoreList":[]}
|
|
@@ -25,6 +25,12 @@ export const useKeyboardAnimation = () => {
|
|
|
25
25
|
progress.value = e.progress;
|
|
26
26
|
height.value = e.height;
|
|
27
27
|
},
|
|
28
|
+
onInteractive: e => {
|
|
29
|
+
"worklet";
|
|
30
|
+
|
|
31
|
+
progress.value = e.progress;
|
|
32
|
+
height.value = e.height;
|
|
33
|
+
},
|
|
28
34
|
onEnd: e => {
|
|
29
35
|
"worklet";
|
|
30
36
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useSharedValue","useKeyboardContext","useKeyboardHandler","useKeyboardAnimation","reanimated","heightWhenOpened","height","value","progress","isClosed","onStart","e","onMove","onEnd"],"sources":["hooks.ts"],"sourcesContent":["import { useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardContext } from \"../../context\";\nimport { useKeyboardHandler } from \"../../hooks\";\n\nexport const useKeyboardAnimation = () => {\n const { reanimated } = useKeyboardContext();\n const heightWhenOpened = useSharedValue(-reanimated.height.value);\n const height = useSharedValue(-reanimated.height.value);\n const progress = useSharedValue(reanimated.progress.value);\n const isClosed = useSharedValue(reanimated.progress.value === 0);\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n isClosed.value = false;\n heightWhenOpened.value = e.height;\n }\n },\n onMove: (e) => {\n \"worklet\";\n\n progress.value = e.progress;\n height.value = e.height;\n },\n onEnd: (e) => {\n \"worklet\";\n\n isClosed.value = e.height === 0;\n\n height.value = e.height;\n progress.value = e.progress;\n },\n },\n [],\n );\n\n return { height, progress, heightWhenOpened, isClosed };\n};\n"],"mappings":"AAAA,SAASA,cAAc,QAAQ,yBAAyB;AAExD,SAASC,kBAAkB,QAAQ,eAAe;AAClD,SAASC,kBAAkB,QAAQ,aAAa;AAEhD,OAAO,MAAMC,oBAAoB,GAAGA,CAAA,KAAM;EACxC,MAAM;IAAEC;EAAW,CAAC,GAAGH,kBAAkB,CAAC,CAAC;EAC3C,MAAMI,gBAAgB,GAAGL,cAAc,CAAC,CAACI,UAAU,CAACE,MAAM,CAACC,KAAK,CAAC;EACjE,MAAMD,MAAM,GAAGN,cAAc,CAAC,CAACI,UAAU,CAACE,MAAM,CAACC,KAAK,CAAC;EACvD,MAAMC,QAAQ,GAAGR,cAAc,CAACI,UAAU,CAACI,QAAQ,CAACD,KAAK,CAAC;EAC1D,MAAME,QAAQ,GAAGT,cAAc,CAACI,UAAU,CAACI,QAAQ,CAACD,KAAK,KAAK,CAAC,CAAC;EAEhEL,kBAAkB,CAChB;IACEQ,OAAO,EAAGC,CAAC,IAAK;MACd,SAAS;;MAET,IAAIA,CAAC,CAACL,MAAM,GAAG,CAAC,EAAE;QAChB;QACAG,QAAQ,CAACF,KAAK,GAAG,KAAK;QACtBF,gBAAgB,CAACE,KAAK,GAAGI,CAAC,CAACL,MAAM;MACnC;IACF,CAAC;IACDM,MAAM,EAAGD,CAAC,IAAK;MACb,SAAS;;MAETH,QAAQ,CAACD,KAAK,GAAGI,CAAC,CAACH,QAAQ;MAC3BF,MAAM,CAACC,KAAK,GAAGI,CAAC,CAACL,MAAM;IACzB,CAAC;IACDO,
|
|
1
|
+
{"version":3,"names":["useSharedValue","useKeyboardContext","useKeyboardHandler","useKeyboardAnimation","reanimated","heightWhenOpened","height","value","progress","isClosed","onStart","e","onMove","onInteractive","onEnd"],"sources":["hooks.ts"],"sourcesContent":["import { useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardContext } from \"../../context\";\nimport { useKeyboardHandler } from \"../../hooks\";\n\nexport const useKeyboardAnimation = () => {\n const { reanimated } = useKeyboardContext();\n const heightWhenOpened = useSharedValue(-reanimated.height.value);\n const height = useSharedValue(-reanimated.height.value);\n const progress = useSharedValue(reanimated.progress.value);\n const isClosed = useSharedValue(reanimated.progress.value === 0);\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n isClosed.value = false;\n heightWhenOpened.value = e.height;\n }\n },\n onMove: (e) => {\n \"worklet\";\n\n progress.value = e.progress;\n height.value = e.height;\n },\n onInteractive: (e) => {\n \"worklet\";\n\n progress.value = e.progress;\n height.value = e.height;\n },\n onEnd: (e) => {\n \"worklet\";\n\n isClosed.value = e.height === 0;\n\n height.value = e.height;\n progress.value = e.progress;\n },\n },\n [],\n );\n\n return { height, progress, heightWhenOpened, isClosed };\n};\n"],"mappings":"AAAA,SAASA,cAAc,QAAQ,yBAAyB;AAExD,SAASC,kBAAkB,QAAQ,eAAe;AAClD,SAASC,kBAAkB,QAAQ,aAAa;AAEhD,OAAO,MAAMC,oBAAoB,GAAGA,CAAA,KAAM;EACxC,MAAM;IAAEC;EAAW,CAAC,GAAGH,kBAAkB,CAAC,CAAC;EAC3C,MAAMI,gBAAgB,GAAGL,cAAc,CAAC,CAACI,UAAU,CAACE,MAAM,CAACC,KAAK,CAAC;EACjE,MAAMD,MAAM,GAAGN,cAAc,CAAC,CAACI,UAAU,CAACE,MAAM,CAACC,KAAK,CAAC;EACvD,MAAMC,QAAQ,GAAGR,cAAc,CAACI,UAAU,CAACI,QAAQ,CAACD,KAAK,CAAC;EAC1D,MAAME,QAAQ,GAAGT,cAAc,CAACI,UAAU,CAACI,QAAQ,CAACD,KAAK,KAAK,CAAC,CAAC;EAEhEL,kBAAkB,CAChB;IACEQ,OAAO,EAAGC,CAAC,IAAK;MACd,SAAS;;MAET,IAAIA,CAAC,CAACL,MAAM,GAAG,CAAC,EAAE;QAChB;QACAG,QAAQ,CAACF,KAAK,GAAG,KAAK;QACtBF,gBAAgB,CAACE,KAAK,GAAGI,CAAC,CAACL,MAAM;MACnC;IACF,CAAC;IACDM,MAAM,EAAGD,CAAC,IAAK;MACb,SAAS;;MAETH,QAAQ,CAACD,KAAK,GAAGI,CAAC,CAACH,QAAQ;MAC3BF,MAAM,CAACC,KAAK,GAAGI,CAAC,CAACL,MAAM;IACzB,CAAC;IACDO,aAAa,EAAGF,CAAC,IAAK;MACpB,SAAS;;MAETH,QAAQ,CAACD,KAAK,GAAGI,CAAC,CAACH,QAAQ;MAC3BF,MAAM,CAACC,KAAK,GAAGI,CAAC,CAACL,MAAM;IACzB,CAAC;IACDQ,KAAK,EAAGH,CAAC,IAAK;MACZ,SAAS;;MAETF,QAAQ,CAACF,KAAK,GAAGI,CAAC,CAACL,MAAM,KAAK,CAAC;MAE/BA,MAAM,CAACC,KAAK,GAAGI,CAAC,CAACL,MAAM;MACvBE,QAAQ,CAACD,KAAK,GAAGI,CAAC,CAACH,QAAQ;IAC7B;EACF,CAAC,EACD,EACF,CAAC;EAED,OAAO;IAAEF,MAAM;IAAEE,QAAQ;IAAEH,gBAAgB;IAAEI;EAAS,CAAC;AACzD,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -27,6 +27,12 @@ export const useKeyboardAnimation = () => {
|
|
|
27
27
|
progress.value = e.progress;
|
|
28
28
|
height.value = e.height;
|
|
29
29
|
},
|
|
30
|
+
onInteractive: (e) => {
|
|
31
|
+
"worklet";
|
|
32
|
+
|
|
33
|
+
progress.value = e.progress;
|
|
34
|
+
height.value = e.height;
|
|
35
|
+
},
|
|
30
36
|
onEnd: (e) => {
|
|
31
37
|
"worklet";
|
|
32
38
|
|