react-native-keyboard-controller 1.13.3 → 1.14.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.
Files changed (121) hide show
  1. package/README.md +1 -0
  2. package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +5 -3
  3. package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt +19 -20
  4. package/android/src/fabric/java/com/reactnativekeyboardcontroller/KeyboardGestureAreaViewManager.kt +22 -12
  5. package/android/src/fabric/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt +40 -0
  6. package/android/src/fabric/java/com/reactnativekeyboardcontroller/StatusBarManagerCompatModule.kt +7 -3
  7. package/android/src/main/java/com/reactnativekeyboardcontroller/KeyboardControllerPackage.kt +33 -27
  8. package/android/src/main/java/com/reactnativekeyboardcontroller/events/FocusedInputLayoutChangedEvent.kt +16 -15
  9. package/android/src/main/java/com/reactnativekeyboardcontroller/events/FocusedInputSelectionChangedEvent.kt +25 -24
  10. package/android/src/main/java/com/reactnativekeyboardcontroller/events/FocusedInputTextChangedEvent.kt +4 -3
  11. package/android/src/main/java/com/reactnativekeyboardcontroller/events/KeyboardTransitionEvent.kt +7 -6
  12. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/Context.kt +38 -0
  13. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt +82 -62
  14. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ReactContext.kt +9 -4
  15. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt +12 -5
  16. package/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt +12 -10
  17. package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/KeyboardAnimationController.kt +65 -60
  18. package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/interpolators/Interpolator.kt +6 -1
  19. package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/interpolators/IosInterpolator.kt +4 -2
  20. package/android/src/main/java/com/reactnativekeyboardcontroller/interactive/interpolators/LinearInterpolator.kt +1 -3
  21. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/FocusedInputObserver.kt +62 -58
  22. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +52 -46
  23. package/android/src/main/java/com/reactnativekeyboardcontroller/listeners/WindowDimensionListener.kt +13 -7
  24. package/android/src/main/java/com/reactnativekeyboardcontroller/log/Logger.kt +28 -0
  25. package/android/src/main/java/com/reactnativekeyboardcontroller/managers/KeyboardControllerViewManagerImpl.kt +35 -24
  26. package/android/src/main/java/com/reactnativekeyboardcontroller/managers/KeyboardGestureAreaViewManagerImpl.kt +21 -8
  27. package/android/src/main/java/com/reactnativekeyboardcontroller/managers/OverKeyboardViewManagerImpl.kt +27 -0
  28. package/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt +15 -13
  29. package/android/src/main/java/com/reactnativekeyboardcontroller/modules/KeyboardControllerModuleImpl.kt +8 -8
  30. package/android/src/main/java/com/reactnativekeyboardcontroller/modules/StatusBarManagerCompatModuleImpl.kt +10 -5
  31. package/android/src/main/java/com/reactnativekeyboardcontroller/traversal/FocusedInputHolder.kt +1 -3
  32. package/android/src/main/java/com/reactnativekeyboardcontroller/traversal/ViewHierarchyNavigator.kt +19 -13
  33. package/android/src/main/java/com/reactnativekeyboardcontroller/ui/FrameScheduler.kt +11 -8
  34. package/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +24 -19
  35. package/android/src/main/java/com/reactnativekeyboardcontroller/views/KeyboardGestureAreaReactViewGroup.kt +23 -14
  36. package/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardHostShadowNode.kt +30 -0
  37. package/android/src/main/java/com/reactnativekeyboardcontroller/views/overlay/OverKeyboardViewGroup.kt +185 -0
  38. package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerModule.kt +3 -1
  39. package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardControllerViewManager.kt +19 -10
  40. package/android/src/paper/java/com/reactnativekeyboardcontroller/KeyboardGestureAreaViewManager.kt +21 -8
  41. package/android/src/paper/java/com/reactnativekeyboardcontroller/OverKeyboardViewManager.kt +33 -0
  42. package/android/src/paper/java/com/reactnativekeyboardcontroller/StatusBarManagerCompatModule.kt +7 -3
  43. package/android/src/test/java/com/reactnativekeyboardcontroller/traversal/ViewHierarchyNavigatorTest.kt +30 -21
  44. package/ios/KeyboardController-Bridging-Header.h +1 -0
  45. package/ios/extensions/UIResponder.swift +0 -3
  46. package/ios/extensions/UIWindow.swift +48 -0
  47. package/ios/views/OverKeyboardViewManager.h +29 -0
  48. package/ios/views/OverKeyboardViewManager.mm +220 -0
  49. package/jest/index.js +1 -0
  50. package/lib/commonjs/bindings.js +2 -1
  51. package/lib/commonjs/bindings.js.map +1 -1
  52. package/lib/commonjs/bindings.native.js +2 -1
  53. package/lib/commonjs/bindings.native.js.map +1 -1
  54. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +2 -1
  55. package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
  56. package/lib/commonjs/components/KeyboardToolbar/index.js +5 -3
  57. package/lib/commonjs/components/KeyboardToolbar/index.js.map +1 -1
  58. package/lib/commonjs/hooks/index.js +2 -4
  59. package/lib/commonjs/hooks/index.js.map +1 -1
  60. package/lib/commonjs/index.js +9 -1
  61. package/lib/commonjs/index.js.map +1 -1
  62. package/lib/commonjs/internal.js +24 -12
  63. package/lib/commonjs/internal.js.map +1 -1
  64. package/lib/commonjs/specs/OverKeyboardViewNativeComponent.js +10 -0
  65. package/lib/commonjs/specs/OverKeyboardViewNativeComponent.js.map +1 -0
  66. package/lib/commonjs/types.js.map +1 -1
  67. package/lib/commonjs/views/OverKeyboardView/index.js +43 -0
  68. package/lib/commonjs/views/OverKeyboardView/index.js.map +1 -0
  69. package/lib/commonjs/views/index.js +14 -0
  70. package/lib/commonjs/views/index.js.map +1 -0
  71. package/lib/module/bindings.js +1 -0
  72. package/lib/module/bindings.js.map +1 -1
  73. package/lib/module/bindings.native.js +1 -0
  74. package/lib/module/bindings.native.js.map +1 -1
  75. package/lib/module/components/KeyboardAwareScrollView/index.js +2 -1
  76. package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
  77. package/lib/module/components/KeyboardToolbar/index.js +5 -3
  78. package/lib/module/components/KeyboardToolbar/index.js.map +1 -1
  79. package/lib/module/hooks/index.js +3 -4
  80. package/lib/module/hooks/index.js.map +1 -1
  81. package/lib/module/index.js +1 -0
  82. package/lib/module/index.js.map +1 -1
  83. package/lib/module/internal.js +24 -12
  84. package/lib/module/internal.js.map +1 -1
  85. package/lib/module/specs/OverKeyboardViewNativeComponent.js +3 -0
  86. package/lib/module/specs/OverKeyboardViewNativeComponent.js.map +1 -0
  87. package/lib/module/types.js.map +1 -1
  88. package/lib/module/views/OverKeyboardView/index.js +35 -0
  89. package/lib/module/views/OverKeyboardView/index.js.map +1 -0
  90. package/lib/module/views/index.js +2 -0
  91. package/lib/module/views/index.js.map +1 -0
  92. package/lib/typescript/bindings.d.ts +2 -1
  93. package/lib/typescript/bindings.native.d.ts +2 -1
  94. package/lib/typescript/components/KeyboardAwareScrollView/index.d.ts +4 -0
  95. package/lib/typescript/components/KeyboardToolbar/index.d.ts +2 -2
  96. package/lib/typescript/index.d.ts +1 -0
  97. package/lib/typescript/specs/OverKeyboardViewNativeComponent.d.ts +7 -0
  98. package/lib/typescript/types.d.ts +4 -1
  99. package/lib/typescript/views/OverKeyboardView/index.d.ts +5 -0
  100. package/lib/typescript/views/index.d.ts +1 -0
  101. package/package.json +8 -3
  102. package/src/bindings.native.ts +3 -0
  103. package/src/bindings.ts +3 -0
  104. package/src/components/KeyboardAwareScrollView/index.tsx +5 -2
  105. package/src/components/KeyboardToolbar/index.tsx +7 -3
  106. package/src/hooks/index.ts +3 -5
  107. package/src/index.ts +1 -0
  108. package/src/internal.ts +34 -15
  109. package/src/specs/OverKeyboardViewNativeComponent.ts +12 -0
  110. package/src/types.ts +4 -0
  111. package/src/views/OverKeyboardView/index.tsx +43 -0
  112. package/src/views/index.ts +1 -0
  113. package/ios/.clang-format +0 -90
  114. package/ios/.swiftformat +0 -5
  115. package/ios/.swiftlint.yml +0 -14
  116. package/lib/commonjs/hooks/useSyncEffect/index.js +0 -37
  117. package/lib/commonjs/hooks/useSyncEffect/index.js.map +0 -1
  118. package/lib/module/hooks/useSyncEffect/index.js +0 -31
  119. package/lib/module/hooks/useSyncEffect/index.js.map +0 -1
  120. package/lib/typescript/hooks/useSyncEffect/index.d.ts +0 -14
  121. package/src/hooks/useSyncEffect/index.ts +0 -36
package/README.md CHANGED
@@ -15,6 +15,7 @@ Keyboard manager which works in identical way on both iOS and Android.
15
15
  - interactive keyboard dismissing 👆📱
16
16
  - prebuilt components (`KeyboardStickyView`, `KeyboardAwareScrollView`, re-worked `KeyboardAvoidingView`) 📚
17
17
  - `KeyboardToolbar` with easy behavior customization of _**previous**_, _**next**_ and _**done**_ buttons in the keyboard toolbar 📐
18
+ - show anything over the keyboard (without dismissing it) using `OverKeyboardView` 🌐
18
19
  - easy focused input information retrieval 📝 🔮
19
20
  - works with any navigation library 🧭
20
21
  - and more is coming... Stay tuned! 😊
@@ -3,7 +3,9 @@ package com.reactnativekeyboardcontroller
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.reactnativekeyboardcontroller.modules.KeyboardControllerModuleImpl
5
5
 
6
- class KeyboardControllerModule(mReactContext: ReactApplicationContext) : NativeKeyboardControllerSpec(mReactContext) {
6
+ class KeyboardControllerModule(
7
+ mReactContext: ReactApplicationContext,
8
+ ) : NativeKeyboardControllerSpec(mReactContext) {
7
9
  private val module = KeyboardControllerModuleImpl(mReactContext)
8
10
 
9
11
  override fun getName(): String = KeyboardControllerModuleImpl.NAME
@@ -25,10 +27,10 @@ class KeyboardControllerModule(mReactContext: ReactApplicationContext) : NativeK
25
27
  }
26
28
 
27
29
  override fun addListener(eventName: String?) {
28
- /* Required for RN built-in Event Emitter Calls. */
30
+ // Required for RN built-in Event Emitter Calls.
29
31
  }
30
32
 
31
33
  override fun removeListeners(count: Double) {
32
- /* Required for RN built-in Event Emitter Calls. */
34
+ // Required for RN built-in Event Emitter Calls.
33
35
  }
34
36
  }
@@ -11,38 +11,37 @@ import com.facebook.react.views.view.ReactViewManager
11
11
  import com.reactnativekeyboardcontroller.managers.KeyboardControllerViewManagerImpl
12
12
  import com.reactnativekeyboardcontroller.views.EdgeToEdgeReactViewGroup
13
13
 
14
- class KeyboardControllerViewManager(mReactContext: ReactApplicationContext) :
15
- ReactViewManager(),
14
+ class KeyboardControllerViewManager(
15
+ mReactContext: ReactApplicationContext,
16
+ ) : ReactViewManager(),
16
17
  KeyboardControllerViewManagerInterface<ReactViewGroup> {
17
18
  private val manager = KeyboardControllerViewManagerImpl(mReactContext)
18
19
  private val mDelegate = KeyboardControllerViewManagerDelegate(this)
19
20
 
20
- override fun getDelegate(): ViewManagerDelegate<ReactViewGroup?> {
21
- return mDelegate
22
- }
21
+ override fun getDelegate(): ViewManagerDelegate<ReactViewGroup?> = mDelegate
23
22
 
24
23
  override fun getName(): String = KeyboardControllerViewManagerImpl.NAME
25
24
 
26
- override fun createViewInstance(context: ThemedReactContext): ReactViewGroup {
27
- return manager.createViewInstance(context)
28
- }
25
+ override fun createViewInstance(context: ThemedReactContext): ReactViewGroup = manager.createViewInstance(context)
29
26
 
30
27
  @ReactProp(name = "statusBarTranslucent")
31
- override fun setStatusBarTranslucent(view: ReactViewGroup, value: Boolean) {
32
- return manager.setStatusBarTranslucent(view as EdgeToEdgeReactViewGroup, value)
33
- }
28
+ override fun setStatusBarTranslucent(
29
+ view: ReactViewGroup,
30
+ value: Boolean,
31
+ ) = manager.setStatusBarTranslucent(view as EdgeToEdgeReactViewGroup, value)
34
32
 
35
33
  @ReactProp(name = "navigationBarTranslucent")
36
- override fun setNavigationBarTranslucent(view: ReactViewGroup, value: Boolean) {
37
- return manager.setNavigationBarTranslucent(view as EdgeToEdgeReactViewGroup, value)
38
- }
34
+ override fun setNavigationBarTranslucent(
35
+ view: ReactViewGroup,
36
+ value: Boolean,
37
+ ) = manager.setNavigationBarTranslucent(view as EdgeToEdgeReactViewGroup, value)
39
38
 
40
39
  @ReactProp(name = "enabled")
41
- override fun setEnabled(view: ReactViewGroup, value: Boolean) {
42
- return manager.setEnabled(view as EdgeToEdgeReactViewGroup, value)
43
- }
40
+ override fun setEnabled(
41
+ view: ReactViewGroup,
42
+ value: Boolean,
43
+ ) = manager.setEnabled(view as EdgeToEdgeReactViewGroup, value)
44
44
 
45
- override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
46
- return manager.getExportedCustomDirectEventTypeConstants()
47
- }
45
+ override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
46
+ manager.getExportedCustomDirectEventTypeConstants()
48
47
  }
@@ -11,39 +11,49 @@ import com.facebook.react.views.view.ReactViewManager
11
11
  import com.reactnativekeyboardcontroller.managers.KeyboardGestureAreaViewManagerImpl
12
12
  import com.reactnativekeyboardcontroller.views.KeyboardGestureAreaReactViewGroup
13
13
 
14
- class KeyboardGestureAreaViewManager(mReactContext: ReactApplicationContext) :
15
- ReactViewManager(),
14
+ class KeyboardGestureAreaViewManager(
15
+ mReactContext: ReactApplicationContext,
16
+ ) : ReactViewManager(),
16
17
  KeyboardGestureAreaManagerInterface<ReactViewGroup> {
17
18
  private val manager = KeyboardGestureAreaViewManagerImpl(mReactContext)
18
19
  private val mDelegate = KeyboardGestureAreaManagerDelegate(this)
19
20
 
20
- override fun getDelegate(): ViewManagerDelegate<ReactViewGroup?> {
21
- return mDelegate
22
- }
21
+ override fun getDelegate(): ViewManagerDelegate<ReactViewGroup?> = mDelegate
23
22
 
24
23
  override fun getName(): String = KeyboardGestureAreaViewManagerImpl.NAME
25
24
 
26
- override fun createViewInstance(context: ThemedReactContext): KeyboardGestureAreaReactViewGroup {
27
- return manager.createViewInstance(context)
28
- }
25
+ override fun createViewInstance(context: ThemedReactContext): KeyboardGestureAreaReactViewGroup =
26
+ manager.createViewInstance(context)
29
27
 
30
28
  @ReactProp(name = "offset")
31
- override fun setOffset(view: ReactViewGroup, value: Double) {
29
+ override fun setOffset(
30
+ view: ReactViewGroup,
31
+ value: Double,
32
+ ) {
32
33
  manager.setOffset(view as KeyboardGestureAreaReactViewGroup, value)
33
34
  }
34
35
 
35
36
  @ReactProp(name = "interpolator")
36
- override fun setInterpolator(view: ReactViewGroup, value: String?) {
37
+ override fun setInterpolator(
38
+ view: ReactViewGroup,
39
+ value: String?,
40
+ ) {
37
41
  manager.setInterpolator(view as KeyboardGestureAreaReactViewGroup, value ?: "linear")
38
42
  }
39
43
 
40
44
  @ReactProp(name = "showOnSwipeUp")
41
- override fun setShowOnSwipeUp(view: ReactViewGroup, value: Boolean) {
45
+ override fun setShowOnSwipeUp(
46
+ view: ReactViewGroup,
47
+ value: Boolean,
48
+ ) {
42
49
  manager.setScrollKeyboardOnScreenWhenNotVisible(view as KeyboardGestureAreaReactViewGroup, value)
43
50
  }
44
51
 
45
52
  @ReactProp(name = "enableSwipeToDismiss")
46
- override fun setEnableSwipeToDismiss(view: ReactViewGroup?, value: Boolean) {
53
+ override fun setEnableSwipeToDismiss(
54
+ view: ReactViewGroup?,
55
+ value: Boolean,
56
+ ) {
47
57
  manager.setScrollKeyboardOffScreenWhenVisible(view as KeyboardGestureAreaReactViewGroup, value)
48
58
  }
49
59
  }
@@ -0,0 +1,40 @@
1
+ package com.reactnativekeyboardcontroller
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.uimanager.LayoutShadowNode
5
+ import com.facebook.react.uimanager.ThemedReactContext
6
+ import com.facebook.react.uimanager.ViewGroupManager
7
+ import com.facebook.react.uimanager.ViewManagerDelegate
8
+ import com.facebook.react.uimanager.annotations.ReactProp
9
+ import com.facebook.react.viewmanagers.OverKeyboardViewManagerDelegate
10
+ import com.facebook.react.viewmanagers.OverKeyboardViewManagerInterface
11
+ import com.reactnativekeyboardcontroller.managers.OverKeyboardViewManagerImpl
12
+ import com.reactnativekeyboardcontroller.views.overlay.OverKeyboardHostShadowNode
13
+ import com.reactnativekeyboardcontroller.views.overlay.OverKeyboardHostView
14
+
15
+ class OverKeyboardViewManager(
16
+ mReactContext: ReactApplicationContext,
17
+ ) : ViewGroupManager<OverKeyboardHostView>(),
18
+ OverKeyboardViewManagerInterface<OverKeyboardHostView> {
19
+ private val manager = OverKeyboardViewManagerImpl(mReactContext)
20
+ private val mDelegate = OverKeyboardViewManagerDelegate(this)
21
+
22
+ override fun getDelegate(): ViewManagerDelegate<OverKeyboardHostView?> = mDelegate
23
+
24
+ override fun getName(): String = OverKeyboardViewManagerImpl.NAME
25
+
26
+ override fun createViewInstance(context: ThemedReactContext): OverKeyboardHostView =
27
+ manager.createViewInstance(context)
28
+
29
+ override fun createShadowNodeInstance(): LayoutShadowNode = OverKeyboardHostShadowNode()
30
+
31
+ override fun getShadowNodeClass(): Class<out LayoutShadowNode> = OverKeyboardHostShadowNode::class.java
32
+
33
+ @ReactProp(name = "visible")
34
+ override fun setVisible(
35
+ view: OverKeyboardHostView,
36
+ value: Boolean,
37
+ ) {
38
+ manager.setVisible(view, value)
39
+ }
40
+ }
@@ -3,8 +3,9 @@ package com.reactnativekeyboardcontroller
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.reactnativekeyboardcontroller.modules.StatusBarManagerCompatModuleImpl
5
5
 
6
- class StatusBarManagerCompatModule(mReactContext: ReactApplicationContext) :
7
- NativeStatusBarManagerCompatSpec(mReactContext) {
6
+ class StatusBarManagerCompatModule(
7
+ mReactContext: ReactApplicationContext,
8
+ ) : NativeStatusBarManagerCompatSpec(mReactContext) {
8
9
  private val module = StatusBarManagerCompatModuleImpl(mReactContext)
9
10
 
10
11
  override fun getName(): String = StatusBarManagerCompatModuleImpl.NAME
@@ -13,7 +14,10 @@ class StatusBarManagerCompatModule(mReactContext: ReactApplicationContext) :
13
14
  module.setHidden(hidden)
14
15
  }
15
16
 
16
- override fun setColor(color: Double, animated: Boolean) {
17
+ override fun setColor(
18
+ color: Double,
19
+ animated: Boolean,
20
+ ) {
17
21
  module.setColor(color.toInt(), animated)
18
22
  }
19
23
 
@@ -12,8 +12,11 @@ import com.reactnativekeyboardcontroller.modules.StatusBarManagerCompatModuleImp
12
12
 
13
13
  class KeyboardControllerPackage : TurboReactPackage() {
14
14
  @Nullable
15
- override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
16
- return when (name) {
15
+ override fun getModule(
16
+ name: String,
17
+ reactContext: ReactApplicationContext,
18
+ ): NativeModule? =
19
+ when (name) {
17
20
  KeyboardControllerModuleImpl.NAME -> {
18
21
  KeyboardControllerModule(reactContext)
19
22
  }
@@ -24,36 +27,39 @@ class KeyboardControllerPackage : TurboReactPackage() {
24
27
  null
25
28
  }
26
29
  }
27
- }
28
30
 
29
- override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
30
- return ReactModuleInfoProvider {
31
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider =
32
+ ReactModuleInfoProvider {
31
33
  val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
32
34
  val isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
33
35
 
34
- moduleInfos[KeyboardControllerModuleImpl.NAME] = ReactModuleInfo(
35
- KeyboardControllerModuleImpl.NAME,
36
- KeyboardControllerModuleImpl.NAME,
37
- false, // canOverrideExistingModule
38
- false, // needsEagerInit
39
- true, // hasConstants
40
- false, // isCxxModule
41
- isTurboModule, // isTurboModule
42
- )
43
- moduleInfos[StatusBarManagerCompatModuleImpl.NAME] = ReactModuleInfo(
44
- StatusBarManagerCompatModuleImpl.NAME,
45
- StatusBarManagerCompatModuleImpl.NAME,
46
- false, // canOverrideExistingModule
47
- false, // needsEagerInit
48
- true, // hasConstants
49
- false, // isCxxModule
50
- isTurboModule, // isTurboModule
51
- )
36
+ moduleInfos[KeyboardControllerModuleImpl.NAME] =
37
+ ReactModuleInfo(
38
+ KeyboardControllerModuleImpl.NAME,
39
+ KeyboardControllerModuleImpl.NAME,
40
+ false, // canOverrideExistingModule
41
+ false, // needsEagerInit
42
+ true, // hasConstants
43
+ false, // isCxxModule
44
+ isTurboModule, // isTurboModule
45
+ )
46
+ moduleInfos[StatusBarManagerCompatModuleImpl.NAME] =
47
+ ReactModuleInfo(
48
+ StatusBarManagerCompatModuleImpl.NAME,
49
+ StatusBarManagerCompatModuleImpl.NAME,
50
+ false, // canOverrideExistingModule
51
+ false, // needsEagerInit
52
+ true, // hasConstants
53
+ false, // isCxxModule
54
+ isTurboModule, // isTurboModule
55
+ )
52
56
  moduleInfos
53
57
  }
54
- }
55
58
 
56
- override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
57
- return listOf(KeyboardControllerViewManager(reactContext), KeyboardGestureAreaViewManager(reactContext))
58
- }
59
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> =
60
+ listOf(
61
+ KeyboardControllerViewManager(reactContext),
62
+ KeyboardGestureAreaViewManager(reactContext),
63
+ OverKeyboardViewManager(reactContext),
64
+ )
59
65
  }
@@ -25,19 +25,20 @@ class FocusedInputLayoutChangedEvent(
25
25
  // All events for a given view can be coalesced
26
26
  override fun getCoalescingKey(): Short = 0
27
27
 
28
- override fun getEventData(): WritableMap? = Arguments.createMap().apply {
29
- putInt("target", event.target)
30
- putInt("parentScrollViewTarget", event.parentScrollViewTarget)
31
- putMap(
32
- "layout",
33
- Arguments.createMap().apply {
34
- putDouble("x", event.x)
35
- putDouble("y", event.y)
36
- putDouble("width", event.width)
37
- putDouble("height", event.height)
38
- putDouble("absoluteX", event.absoluteX)
39
- putDouble("absoluteY", event.absoluteY)
40
- },
41
- )
42
- }
28
+ override fun getEventData(): WritableMap? =
29
+ Arguments.createMap().apply {
30
+ putInt("target", event.target)
31
+ putInt("parentScrollViewTarget", event.parentScrollViewTarget)
32
+ putMap(
33
+ "layout",
34
+ Arguments.createMap().apply {
35
+ putDouble("x", event.x)
36
+ putDouble("y", event.y)
37
+ putDouble("width", event.width)
38
+ putDouble("height", event.height)
39
+ putDouble("absoluteX", event.absoluteX)
40
+ putDouble("absoluteY", event.absoluteY)
41
+ },
42
+ )
43
+ }
43
44
  }
@@ -24,28 +24,29 @@ class FocusedInputSelectionChangedEvent(
24
24
  // All events for a given view can be coalesced
25
25
  override fun getCoalescingKey(): Short = 0
26
26
 
27
- override fun getEventData(): WritableMap? = Arguments.createMap().apply {
28
- putInt("target", event.target)
29
- putMap(
30
- "selection",
31
- Arguments.createMap().apply {
32
- putMap(
33
- "start",
34
- Arguments.createMap().apply {
35
- putDouble("x", event.startX)
36
- putDouble("y", event.startY)
37
- putInt("position", event.start)
38
- },
39
- )
40
- putMap(
41
- "end",
42
- Arguments.createMap().apply {
43
- putDouble("x", event.endX)
44
- putDouble("y", event.endY)
45
- putInt("position", event.end)
46
- },
47
- )
48
- },
49
- )
50
- }
27
+ override fun getEventData(): WritableMap? =
28
+ Arguments.createMap().apply {
29
+ putInt("target", event.target)
30
+ putMap(
31
+ "selection",
32
+ Arguments.createMap().apply {
33
+ putMap(
34
+ "start",
35
+ Arguments.createMap().apply {
36
+ putDouble("x", event.startX)
37
+ putDouble("y", event.startY)
38
+ putInt("position", event.start)
39
+ },
40
+ )
41
+ putMap(
42
+ "end",
43
+ Arguments.createMap().apply {
44
+ putDouble("x", event.endX)
45
+ putDouble("y", event.endY)
46
+ putInt("position", event.end)
47
+ },
48
+ )
49
+ },
50
+ )
51
+ }
51
52
  }
@@ -14,7 +14,8 @@ class FocusedInputTextChangedEvent(
14
14
  // All events for a given view can be coalesced
15
15
  override fun getCoalescingKey(): Short = 0
16
16
 
17
- override fun getEventData(): WritableMap? = Arguments.createMap().apply {
18
- putString("text", text)
19
- }
17
+ override fun getEventData(): WritableMap? =
18
+ Arguments.createMap().apply {
19
+ putString("text", text)
20
+ }
20
21
  }
@@ -19,10 +19,11 @@ class KeyboardTransitionEvent(
19
19
  // All events for a given view can be coalesced?
20
20
  override fun getCoalescingKey(): Short = 0
21
21
 
22
- override fun getEventData(): WritableMap? = Arguments.createMap().apply {
23
- putDouble("progress", progress)
24
- putDouble("height", height)
25
- putInt("duration", duration)
26
- putInt("target", target)
27
- }
22
+ override fun getEventData(): WritableMap? =
23
+ Arguments.createMap().apply {
24
+ putDouble("progress", progress)
25
+ putDouble("height", height)
26
+ putInt("duration", duration)
27
+ putInt("target", target)
28
+ }
28
29
  }
@@ -0,0 +1,38 @@
1
+ package com.reactnativekeyboardcontroller.extensions
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Context
5
+ import android.graphics.Point
6
+ import android.os.Build
7
+ import android.view.Display
8
+ import android.view.WindowManager
9
+ import android.view.WindowMetrics
10
+
11
+ @SuppressLint("ObsoleteSdkInt")
12
+ @Suppress("DEPRECATION")
13
+ fun Context.getDisplaySize(): Point {
14
+ val size = Point()
15
+
16
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
17
+ // For API level 30 (Android 11) and above
18
+ val windowManager = getSystemService(WindowManager::class.java)
19
+ val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics
20
+
21
+ val bounds = windowMetrics.bounds
22
+ size.x = bounds.width()
23
+ size.y = bounds.height()
24
+ } else {
25
+ val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
26
+ val display: Display = windowManager.defaultDisplay
27
+
28
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
29
+ display.getRealSize(size) // API level 17 and above
30
+ } else {
31
+ // Fallback for API level < 17
32
+ size.x = display.width
33
+ size.y = display.height
34
+ }
35
+ }
36
+
37
+ return size
38
+ }
@@ -3,11 +3,11 @@ package com.reactnativekeyboardcontroller.extensions
3
3
  import android.os.Build
4
4
  import android.text.Editable
5
5
  import android.text.TextWatcher
6
- import android.util.Log
7
6
  import android.view.View
8
7
  import android.widget.EditText
9
8
  import com.facebook.react.views.scroll.ReactScrollView
10
9
  import com.facebook.react.views.textinput.ReactEditText
10
+ import com.reactnativekeyboardcontroller.log.Logger
11
11
  import com.reactnativekeyboardcontroller.ui.FrameScheduler
12
12
  import java.lang.reflect.Field
13
13
  import kotlin.math.max
@@ -22,22 +22,33 @@ import kotlin.math.min
22
22
  fun EditText.addOnTextChangedListener(action: (String) -> Unit): TextWatcher {
23
23
  var lastText: String? = null
24
24
 
25
- val listener = object : TextWatcher {
26
- @Suppress("detekt:EmptyFunctionBlock")
27
- override fun afterTextChanged(s: Editable?) {}
28
-
29
- @Suppress("detekt:EmptyFunctionBlock")
30
- override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
31
-
32
- override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
33
- val currentText = s.toString()
34
-
35
- if (currentText != lastText) {
36
- lastText = currentText
37
- action(currentText)
25
+ val listener =
26
+ object : TextWatcher {
27
+ @Suppress("detekt:EmptyFunctionBlock")
28
+ override fun afterTextChanged(s: Editable?) = Unit
29
+
30
+ @Suppress("detekt:EmptyFunctionBlock")
31
+ override fun beforeTextChanged(
32
+ s: CharSequence?,
33
+ start: Int,
34
+ count: Int,
35
+ after: Int,
36
+ ) = Unit
37
+
38
+ override fun onTextChanged(
39
+ s: CharSequence?,
40
+ start: Int,
41
+ before: Int,
42
+ count: Int,
43
+ ) {
44
+ val currentText = s.toString()
45
+
46
+ if (currentText != lastText) {
47
+ lastText = currentText
48
+ action(currentText)
49
+ }
38
50
  }
39
51
  }
40
- }
41
52
 
42
53
  // we can not simply call `addTextChangedListener(listener)`, because the issue
43
54
  // https://github.com/kirillzyusko/react-native-keyboard-controller/issues/324
@@ -57,15 +68,15 @@ fun EditText.addOnTextChangedListener(action: (String) -> Unit): TextWatcher {
57
68
 
58
69
  textWatchListeners.add(0, listener)
59
70
  } else {
60
- Log.w(
71
+ Logger.w(
61
72
  javaClass.simpleName,
62
73
  "Can not attach listener because `fieldValue` does not belong to `ArrayList<TextWatcher>`",
63
74
  )
64
75
  }
65
76
  } catch (e: ClassCastException) {
66
- Log.w(javaClass.simpleName, "Can not attach listener because casting failed: ${e.message}")
77
+ Logger.w(javaClass.simpleName, "Can not attach listener because casting failed: ${e.message}")
67
78
  } catch (e: NoSuchFieldException) {
68
- Log.w(javaClass.simpleName, "Can not attach listener because field `mListeners` not found: ${e.message}")
79
+ Logger.w(javaClass.simpleName, "Can not attach listener because field `mListeners` not found: ${e.message}")
69
80
  }
70
81
 
71
82
  return listener
@@ -106,52 +117,61 @@ class KeyboardControllerSelectionWatcher(
106
117
  private var lastSelectionStart: Int = -1
107
118
  private var lastSelectionEnd: Int = -1
108
119
 
109
- private val frameScheduler = FrameScheduler {
110
- val start = editText.selectionStart
111
- val end = editText.selectionEnd
112
-
113
- if (lastSelectionStart != start || lastSelectionEnd != end) {
114
- lastSelectionStart = start
115
- lastSelectionEnd = end
116
-
117
- val view = editText
118
- val layout = view.layout
119
-
120
- if (layout === null) {
121
- return@FrameScheduler
120
+ private val frameScheduler =
121
+ FrameScheduler {
122
+ val start = editText.selectionStart
123
+ val end = editText.selectionEnd
124
+
125
+ if (lastSelectionStart != start || lastSelectionEnd != end) {
126
+ lastSelectionStart = start
127
+ lastSelectionEnd = end
128
+
129
+ val view = editText
130
+ val layout = view.layout
131
+
132
+ if (layout === null) {
133
+ return@FrameScheduler
134
+ }
135
+
136
+ val cursorPositionStartX: Float
137
+ val cursorPositionStartY: Float
138
+ val cursorPositionEndX: Float
139
+ val cursorPositionEndY: Float
140
+
141
+ val realStart = min(start, end)
142
+ val realEnd = max(start, end)
143
+
144
+ val lineStart = layout.getLineForOffset(realStart)
145
+ val baselineStart = layout.getLineBaseline(lineStart)
146
+ val ascentStart = layout.getLineAscent(lineStart)
147
+
148
+ cursorPositionStartX = layout.getPrimaryHorizontal(realStart)
149
+ cursorPositionStartY = (baselineStart + ascentStart).toFloat()
150
+
151
+ val lineEnd = layout.getLineForOffset(realEnd)
152
+
153
+ val right = layout.getPrimaryHorizontal(realEnd)
154
+ val bottom = layout.getLineBottom(lineEnd) + layout.getLineAscent(lineEnd)
155
+ val cursorWidth =
156
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
157
+ view.textCursorDrawable?.intrinsicWidth ?: 0
158
+ } else {
159
+ 0
160
+ }
161
+
162
+ cursorPositionEndX = right + cursorWidth
163
+ cursorPositionEndY = bottom.toFloat()
164
+
165
+ action(
166
+ start,
167
+ end,
168
+ cursorPositionStartX.dp,
169
+ cursorPositionStartY.dp,
170
+ cursorPositionEndX.dp,
171
+ cursorPositionEndY.dp,
172
+ )
122
173
  }
123
-
124
- val cursorPositionStartX: Float
125
- val cursorPositionStartY: Float
126
- val cursorPositionEndX: Float
127
- val cursorPositionEndY: Float
128
-
129
- val realStart = min(start, end)
130
- val realEnd = max(start, end)
131
-
132
- val lineStart = layout.getLineForOffset(realStart)
133
- val baselineStart = layout.getLineBaseline(lineStart)
134
- val ascentStart = layout.getLineAscent(lineStart)
135
-
136
- cursorPositionStartX = layout.getPrimaryHorizontal(realStart)
137
- cursorPositionStartY = (baselineStart + ascentStart).toFloat()
138
-
139
- val lineEnd = layout.getLineForOffset(realEnd)
140
-
141
- val right = layout.getPrimaryHorizontal(realEnd)
142
- val bottom = layout.getLineBottom(lineEnd) + layout.getLineAscent(lineEnd)
143
- val cursorWidth = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
144
- view.textCursorDrawable?.intrinsicWidth ?: 0
145
- } else {
146
- 0
147
- }
148
-
149
- cursorPositionEndX = right + cursorWidth
150
- cursorPositionEndY = bottom.toFloat()
151
-
152
- action(start, end, cursorPositionStartX.dp, cursorPositionStartY.dp, cursorPositionEndX.dp, cursorPositionEndY.dp)
153
174
  }
154
- }
155
175
 
156
176
  fun setup() {
157
177
  frameScheduler.start()