react-native-external-keyboard 0.9.1 → 1.0.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 (372) hide show
  1. package/README.md +95 -600
  2. package/android/build.gradle +0 -18
  3. package/android/src/main/java/com/externalkeyboard/ExternalKeyboardViewPackage.java +24 -22
  4. package/android/src/main/java/com/externalkeyboard/events/EventHelper.java +10 -13
  5. package/android/src/main/java/com/externalkeyboard/helper/FocusHelper.java +1 -2
  6. package/android/src/main/java/com/externalkeyboard/services/FocusMemoryService.java +64 -0
  7. package/android/src/main/java/com/externalkeyboard/services/KeyboardFocusService.java +41 -0
  8. package/android/src/main/java/com/externalkeyboard/services/KeyboardService.java +4 -13
  9. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardView.java +2 -8
  10. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardViewManager.java +20 -13
  11. package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapper.java +99 -21
  12. package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapperManager.java +11 -0
  13. package/android/src/main/java/com/externalkeyboard/views/base/FocusHighlightBase.java +11 -5
  14. package/android/src/main/java/com/externalkeyboard/views/base/FocusableBase.java +36 -0
  15. package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewFocusChangeBase.java +2 -3
  16. package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewFocusRequestBase.java +10 -61
  17. package/android/src/newarch/ExternalKeyboardLockViewManagerInterface.java +11 -0
  18. package/android/src/newarch/ExternalKeyboardLockViewManagerSpec.java +0 -1
  19. package/android/src/newarch/ExternalKeyboardViewManagerInterface.java +42 -0
  20. package/android/src/newarch/ExternalKeyboardViewManagerSpec.java +0 -1
  21. package/android/src/newarch/KeyboardFocusGroupManagerInterface.java +12 -0
  22. package/android/src/newarch/KeyboardFocusGroupManagerSpec.java +0 -1
  23. package/android/src/newarch/TextInputFocusWrapperManagerInterface.java +34 -0
  24. package/android/src/newarch/TextInputFocusWrapperManagerSpec.java +0 -10
  25. package/android/src/newarch/helper/ReactNativeEventDispatcher.java +28 -0
  26. package/android/src/oldarch/ExternalKeyboardViewManagerSpec.java +6 -4
  27. package/android/src/oldarch/TextInputFocusWrapperManagerSpec.java +4 -0
  28. package/android/src/oldarch/helper/ReactNativeEventDispatcher.java +15 -0
  29. package/ios/Delegates/RNCEKVFocusDelegate/RNCEKVFocusDelegate.mm +1 -1
  30. package/ios/Delegates/RNCEKVFocusDelegate/RNCEKVFocusProtocol.h +1 -1
  31. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.h +2 -1
  32. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.mm +41 -5
  33. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloProtocol.h +1 -0
  34. package/ios/Extensions/RCTCustomScrollView+RNCEKVExternalKeyboard.mm +5 -6
  35. package/ios/Extensions/RCTEnhancedScrollView+RNCEKVExternalKeyboard.mm +8 -9
  36. package/ios/Extensions/RCTTextInputComponentView+RNCEKVExternalKeyboard.mm +1 -1
  37. package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.h +0 -1
  38. package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.mm +16 -4
  39. package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.mm +7 -10
  40. package/ios/Helpers/RNCEKVNativeProps/RNCEKVNativeProps.h +4 -4
  41. package/ios/Helpers/RNCEKVSwizzleInstanceMethod/RNCEKVSwizzleInstanceMethod.h +19 -0
  42. package/ios/Protocols/RNCEKVCustomFocusEffectProtocol.h +1 -1
  43. package/ios/Services/RNCEKVFocusMemoryService.h +39 -0
  44. package/ios/Services/RNCEKVFocusMemoryService.mm +42 -0
  45. package/ios/Services/RNCEKVKeyboardFocusService.h +28 -0
  46. package/ios/Services/RNCEKVKeyboardFocusService.mm +54 -0
  47. package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.h +2 -0
  48. package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.mm +12 -10
  49. package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.h +1 -1
  50. package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.mm +6 -17
  51. package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.h +1 -0
  52. package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.mm +146 -6
  53. package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.h +2 -0
  54. package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.mm +4 -0
  55. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.h +1 -1
  56. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.mm +8 -4
  57. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.mm +22 -11
  58. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.mm +17 -0
  59. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapperManager.mm +12 -0
  60. package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js +67 -65
  61. package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
  62. package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js +49 -97
  63. package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
  64. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js.map +1 -1
  65. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.js.map +1 -1
  66. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.js.map +1 -1
  67. package/lib/commonjs/components/{KeyboardExtendedInput/KeyboardExtendedInput.types.js → KeyboardFocusGroup/KeyboardFocusGroup.types.js} +1 -1
  68. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.types.js.map +1 -0
  69. package/lib/commonjs/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js +2 -1
  70. package/lib/commonjs/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js.map +1 -1
  71. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js +2 -1
  72. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js.map +1 -1
  73. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +2 -1
  74. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -1
  75. package/lib/commonjs/components/KeyboardFocusView/KeyboardFocusView.js +14 -51
  76. package/lib/commonjs/components/KeyboardFocusView/KeyboardFocusView.js.map +1 -1
  77. package/lib/commonjs/components/index.js +47 -0
  78. package/lib/commonjs/components/index.js.map +1 -1
  79. package/lib/commonjs/index.js +37 -19
  80. package/lib/commonjs/index.js.map +1 -1
  81. package/lib/commonjs/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -3
  82. package/lib/commonjs/nativeSpec/ExternalKeyboardViewNativeComponent.ts +12 -9
  83. package/lib/commonjs/nativeSpec/KeyboardFocusGroupNativeComponent.ts +5 -3
  84. package/lib/commonjs/nativeSpec/TextInputFocusWrapperNativeComponent.ts +7 -3
  85. package/lib/commonjs/types/KeyboardFocusLock.types.js +13 -0
  86. package/lib/commonjs/types/KeyboardFocusLock.types.js.map +1 -1
  87. package/lib/commonjs/types/baseKeyboardView.types.js +6 -0
  88. package/lib/commonjs/types/baseKeyboardView.types.js.map +1 -0
  89. package/lib/commonjs/types/{FocusStyle.js → focus.types.js} +1 -1
  90. package/lib/commonjs/types/{FocusStyle.js.map → focus.types.js.map} +1 -1
  91. package/lib/commonjs/types/focusOrder.types.js +33 -0
  92. package/lib/commonjs/types/focusOrder.types.js.map +1 -0
  93. package/lib/commonjs/types/{WithKeyboardFocus.js → focusStyle.types.js} +1 -1
  94. package/lib/commonjs/types/{WithKeyboardFocus.js.map → focusStyle.types.js.map} +1 -1
  95. package/lib/commonjs/types/index.js +18 -0
  96. package/lib/commonjs/types/index.js.map +1 -1
  97. package/lib/commonjs/types/keyPress.types.js +6 -0
  98. package/lib/{module/types/WithKeyboardFocus.js.map → commonjs/types/keyPress.types.js.map} +1 -1
  99. package/lib/commonjs/types/keyboardInput.types.js +6 -0
  100. package/lib/commonjs/types/keyboardInput.types.js.map +1 -0
  101. package/lib/commonjs/types/withKeyboardFocus.types.js +6 -0
  102. package/lib/commonjs/types/withKeyboardFocus.types.js.map +1 -0
  103. package/lib/commonjs/utils/mapLockFocus.js +37 -0
  104. package/lib/commonjs/utils/mapLockFocus.js.map +1 -0
  105. package/lib/commonjs/utils/useFocusStyle.js +4 -21
  106. package/lib/commonjs/utils/useFocusStyle.js.map +1 -1
  107. package/lib/commonjs/utils/useKeyboardFocusContainer.js +79 -0
  108. package/lib/commonjs/utils/useKeyboardFocusContainer.js.map +1 -0
  109. package/lib/commonjs/utils/useKeyboardPress/useKeyboardPress.android.js +4 -7
  110. package/lib/commonjs/utils/useKeyboardPress/useKeyboardPress.android.js.map +1 -1
  111. package/lib/commonjs/utils/useKeyboardPress/useKeyboardPress.ios.js +3 -6
  112. package/lib/commonjs/utils/useKeyboardPress/useKeyboardPress.ios.js.map +1 -1
  113. package/lib/commonjs/utils/useKeyboardPress/useKeyboardPress.js +9 -7
  114. package/lib/commonjs/utils/useKeyboardPress/useKeyboardPress.js.map +1 -1
  115. package/lib/commonjs/utils/useKeyboardPressState.js +65 -0
  116. package/lib/commonjs/utils/useKeyboardPressState.js.map +1 -0
  117. package/lib/commonjs/utils/useOnFocusChange.js +1 -1
  118. package/lib/commonjs/utils/useOnFocusChange.js.map +1 -1
  119. package/lib/commonjs/utils/useOrderValidation.js +35 -0
  120. package/lib/commonjs/utils/useOrderValidation.js.map +1 -0
  121. package/lib/commonjs/utils/useRenderedChildren.js +34 -0
  122. package/lib/commonjs/utils/useRenderedChildren.js.map +1 -0
  123. package/lib/commonjs/utils/useWrappedOrderProps.js +35 -0
  124. package/lib/commonjs/utils/useWrappedOrderProps.js.map +1 -0
  125. package/lib/commonjs/utils/withKeyboardFocus.js +81 -96
  126. package/lib/commonjs/utils/withKeyboardFocus.js.map +1 -1
  127. package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js +57 -55
  128. package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
  129. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js +51 -99
  130. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
  131. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js.map +1 -1
  132. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.js.map +1 -1
  133. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.js.map +1 -1
  134. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.types.js +4 -0
  135. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.types.js.map +1 -0
  136. package/lib/module/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js +2 -1
  137. package/lib/module/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js.map +1 -1
  138. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js +2 -1
  139. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js.map +1 -1
  140. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +2 -1
  141. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -1
  142. package/lib/module/components/KeyboardFocusView/KeyboardFocusView.js +16 -53
  143. package/lib/module/components/KeyboardFocusView/KeyboardFocusView.js.map +1 -1
  144. package/lib/module/components/index.js +5 -0
  145. package/lib/module/components/index.js.map +1 -1
  146. package/lib/module/index.js +20 -7
  147. package/lib/module/index.js.map +1 -1
  148. package/lib/module/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -3
  149. package/lib/module/nativeSpec/ExternalKeyboardViewNativeComponent.ts +12 -9
  150. package/lib/module/nativeSpec/KeyboardFocusGroupNativeComponent.ts +5 -3
  151. package/lib/module/nativeSpec/TextInputFocusWrapperNativeComponent.ts +7 -3
  152. package/lib/module/types/KeyboardFocusLock.types.js +12 -1
  153. package/lib/module/types/KeyboardFocusLock.types.js.map +1 -1
  154. package/lib/module/types/baseKeyboardView.types.js +4 -0
  155. package/lib/module/types/baseKeyboardView.types.js.map +1 -0
  156. package/lib/module/types/focus.types.js +4 -0
  157. package/lib/module/types/{FocusStyle.js.map → focus.types.js.map} +1 -1
  158. package/lib/module/types/focusOrder.types.js +31 -0
  159. package/lib/module/types/focusOrder.types.js.map +1 -0
  160. package/lib/module/types/focusStyle.types.js +4 -0
  161. package/lib/module/types/focusStyle.types.js.map +1 -0
  162. package/lib/module/types/index.js +3 -0
  163. package/lib/module/types/index.js.map +1 -1
  164. package/lib/module/types/keyPress.types.js +4 -0
  165. package/lib/module/types/keyPress.types.js.map +1 -0
  166. package/lib/module/types/keyboardInput.types.js +4 -0
  167. package/lib/module/types/keyboardInput.types.js.map +1 -0
  168. package/lib/module/types/withKeyboardFocus.types.js +4 -0
  169. package/lib/module/types/withKeyboardFocus.types.js.map +1 -0
  170. package/lib/module/utils/mapLockFocus.js +32 -0
  171. package/lib/module/utils/mapLockFocus.js.map +1 -0
  172. package/lib/module/utils/useFocusStyle.js +4 -21
  173. package/lib/module/utils/useFocusStyle.js.map +1 -1
  174. package/lib/module/utils/useKeyboardFocusContainer.js +74 -0
  175. package/lib/module/utils/useKeyboardFocusContainer.js.map +1 -0
  176. package/lib/module/utils/useKeyboardPress/useKeyboardPress.android.js +4 -7
  177. package/lib/module/utils/useKeyboardPress/useKeyboardPress.android.js.map +1 -1
  178. package/lib/module/utils/useKeyboardPress/useKeyboardPress.ios.js +3 -6
  179. package/lib/module/utils/useKeyboardPress/useKeyboardPress.ios.js.map +1 -1
  180. package/lib/module/utils/useKeyboardPress/useKeyboardPress.js +9 -7
  181. package/lib/module/utils/useKeyboardPress/useKeyboardPress.js.map +1 -1
  182. package/lib/module/utils/useKeyboardPressState.js +60 -0
  183. package/lib/module/utils/useKeyboardPressState.js.map +1 -0
  184. package/lib/module/utils/useOnFocusChange.js +1 -1
  185. package/lib/module/utils/useOnFocusChange.js.map +1 -1
  186. package/lib/module/utils/useOrderValidation.js +30 -0
  187. package/lib/module/utils/useOrderValidation.js.map +1 -0
  188. package/lib/module/utils/useRenderedChildren.js +29 -0
  189. package/lib/module/utils/useRenderedChildren.js.map +1 -0
  190. package/lib/module/utils/useWrappedOrderProps.js +30 -0
  191. package/lib/module/utils/useWrappedOrderProps.js.map +1 -0
  192. package/lib/module/utils/withKeyboardFocus.js +84 -99
  193. package/lib/module/utils/withKeyboardFocus.js.map +1 -1
  194. package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts +30 -10
  195. package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts.map +1 -1
  196. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.d.ts +187 -12
  197. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.d.ts.map +1 -1
  198. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.d.ts +4 -146
  199. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.d.ts.map +1 -1
  200. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.d.ts +2 -12
  201. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.d.ts.map +1 -1
  202. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.d.ts +4 -146
  203. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.d.ts.map +1 -1
  204. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.types.d.ts +13 -0
  205. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.types.d.ts.map +1 -0
  206. package/lib/typescript/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.d.ts +1 -1
  207. package/lib/typescript/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.d.ts.map +1 -1
  208. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.d.ts +1 -1
  209. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.d.ts.map +1 -1
  210. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts +1 -1
  211. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts.map +1 -1
  212. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts +1 -1
  213. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts.map +1 -1
  214. package/lib/typescript/src/components/KeyboardFocusView/KeyboardFocusView.d.ts +28 -18
  215. package/lib/typescript/src/components/KeyboardFocusView/KeyboardFocusView.d.ts.map +1 -1
  216. package/lib/typescript/src/components/Touchable/Pressable.d.ts +14 -14
  217. package/lib/typescript/src/components/Touchable/Pressable.d.ts.map +1 -1
  218. package/lib/typescript/src/components/index.d.ts +5 -0
  219. package/lib/typescript/src/components/index.d.ts.map +1 -1
  220. package/lib/typescript/src/index.d.ts +694 -9
  221. package/lib/typescript/src/index.d.ts.map +1 -1
  222. package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts +2 -4
  223. package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts.map +1 -1
  224. package/lib/typescript/src/nativeSpec/ExternalKeyboardViewNativeComponent.d.ts +6 -7
  225. package/lib/typescript/src/nativeSpec/ExternalKeyboardViewNativeComponent.d.ts.map +1 -1
  226. package/lib/typescript/src/nativeSpec/KeyboardFocusGroupNativeComponent.d.ts +2 -4
  227. package/lib/typescript/src/nativeSpec/KeyboardFocusGroupNativeComponent.d.ts.map +1 -1
  228. package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts +4 -4
  229. package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts.map +1 -1
  230. package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts +15 -1
  231. package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts.map +1 -1
  232. package/lib/typescript/src/types/KeyboardFocusView.types.d.ts +16 -14
  233. package/lib/typescript/src/types/KeyboardFocusView.types.d.ts.map +1 -1
  234. package/lib/typescript/src/types/baseKeyboardView.types.d.ts +119 -0
  235. package/lib/typescript/src/types/baseKeyboardView.types.d.ts.map +1 -0
  236. package/lib/typescript/src/types/focus.types.d.ts +35 -0
  237. package/lib/typescript/src/types/focus.types.d.ts.map +1 -0
  238. package/lib/typescript/src/types/focusOrder.types.d.ts +57 -0
  239. package/lib/typescript/src/types/focusOrder.types.d.ts.map +1 -0
  240. package/lib/typescript/src/types/focusStyle.types.d.ts +11 -0
  241. package/lib/typescript/src/types/focusStyle.types.d.ts.map +1 -0
  242. package/lib/typescript/src/types/index.d.ts +11 -2
  243. package/lib/typescript/src/types/index.d.ts.map +1 -1
  244. package/lib/typescript/src/types/keyPress.types.d.ts +7 -0
  245. package/lib/typescript/src/types/keyPress.types.d.ts.map +1 -0
  246. package/lib/typescript/src/types/keyboardInput.types.d.ts +53 -0
  247. package/lib/typescript/src/types/keyboardInput.types.d.ts.map +1 -0
  248. package/lib/typescript/src/types/withKeyboardFocus.types.d.ts +109 -0
  249. package/lib/typescript/src/types/withKeyboardFocus.types.d.ts.map +1 -0
  250. package/lib/typescript/src/utils/mapLockFocus.d.ts +3 -0
  251. package/lib/typescript/src/utils/mapLockFocus.d.ts.map +1 -0
  252. package/lib/typescript/src/utils/useFocusStyle.d.ts +26 -34
  253. package/lib/typescript/src/utils/useFocusStyle.d.ts.map +1 -1
  254. package/lib/typescript/src/utils/useKeyboardFocusContainer.d.ts +898 -0
  255. package/lib/typescript/src/utils/useKeyboardFocusContainer.d.ts.map +1 -0
  256. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.android.d.ts +2 -2
  257. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.android.d.ts.map +1 -1
  258. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.d.ts +4 -3
  259. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.d.ts.map +1 -1
  260. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.ios.d.ts +3 -3
  261. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.ios.d.ts.map +1 -1
  262. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.types.d.ts +1 -2
  263. package/lib/typescript/src/utils/useKeyboardPress/useKeyboardPress.types.d.ts.map +1 -1
  264. package/lib/typescript/src/utils/useKeyboardPressState.d.ts +29 -0
  265. package/lib/typescript/src/utils/useKeyboardPressState.d.ts.map +1 -0
  266. package/lib/typescript/src/utils/useOnFocusChange.d.ts +3 -3
  267. package/lib/typescript/src/utils/useOnFocusChange.d.ts.map +1 -1
  268. package/lib/typescript/src/utils/useOrderValidation.d.ts +8 -0
  269. package/lib/typescript/src/utils/useOrderValidation.d.ts.map +1 -0
  270. package/lib/typescript/src/utils/useRenderedChildren.d.ts +18 -0
  271. package/lib/typescript/src/utils/useRenderedChildren.d.ts.map +1 -0
  272. package/lib/typescript/src/utils/useWrappedOrderProps.d.ts +13 -0
  273. package/lib/typescript/src/utils/useWrappedOrderProps.d.ts.map +1 -0
  274. package/lib/typescript/src/utils/withKeyboardFocus.d.ts +3 -4
  275. package/lib/typescript/src/utils/withKeyboardFocus.d.ts.map +1 -1
  276. package/package.json +4 -2
  277. package/src/components/BaseKeyboardView/BaseKeyboardView.tsx +74 -94
  278. package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.tsx +49 -149
  279. package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.tsx +23 -32
  280. package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.tsx +32 -41
  281. package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.tsx +3 -14
  282. package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.types.ts +15 -0
  283. package/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.tsx +2 -2
  284. package/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.tsx +2 -2
  285. package/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.tsx +1 -1
  286. package/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.tsx +2 -2
  287. package/src/components/KeyboardFocusView/KeyboardFocusView.tsx +29 -68
  288. package/src/components/Touchable/Pressable.tsx +2 -2
  289. package/src/components/index.ts +12 -0
  290. package/src/index.tsx +44 -32
  291. package/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -3
  292. package/src/nativeSpec/ExternalKeyboardViewNativeComponent.ts +12 -9
  293. package/src/nativeSpec/KeyboardFocusGroupNativeComponent.ts +5 -3
  294. package/src/nativeSpec/TextInputFocusWrapperNativeComponent.ts +7 -3
  295. package/src/types/KeyboardFocusLock.types.ts +16 -1
  296. package/src/types/KeyboardFocusView.types.ts +17 -18
  297. package/src/types/baseKeyboardView.types.ts +122 -0
  298. package/src/types/focus.types.ts +40 -0
  299. package/src/types/focusOrder.types.ts +59 -0
  300. package/src/types/{FocusStyle.ts → focusStyle.types.ts} +5 -0
  301. package/src/types/index.ts +32 -2
  302. package/src/types/keyPress.types.ts +8 -0
  303. package/src/types/keyboardInput.types.ts +81 -0
  304. package/src/types/withKeyboardFocus.types.ts +178 -0
  305. package/src/utils/mapLockFocus.ts +31 -0
  306. package/src/utils/useFocusStyle.tsx +13 -41
  307. package/src/utils/useKeyboardFocusContainer.ts +102 -0
  308. package/src/utils/useKeyboardPress/useKeyboardPress.android.ts +4 -7
  309. package/src/utils/useKeyboardPress/useKeyboardPress.ios.ts +3 -6
  310. package/src/utils/useKeyboardPress/useKeyboardPress.ts +9 -7
  311. package/src/utils/useKeyboardPress/useKeyboardPress.types.ts +1 -2
  312. package/src/utils/useKeyboardPressState.ts +81 -0
  313. package/src/utils/useOnFocusChange.ts +4 -7
  314. package/src/utils/useOrderValidation.ts +74 -0
  315. package/src/utils/useRenderedChildren.ts +42 -0
  316. package/src/utils/useWrappedOrderProps.ts +48 -0
  317. package/src/utils/withKeyboardFocus.tsx +105 -125
  318. package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.types.js.map +0 -1
  319. package/lib/commonjs/components/KeyboardFocusView/hooks/index.js +0 -13
  320. package/lib/commonjs/components/KeyboardFocusView/hooks/index.js.map +0 -1
  321. package/lib/commonjs/components/KeyboardFocusView/hooks/useFocusStyle/index.js +0 -13
  322. package/lib/commonjs/components/KeyboardFocusView/hooks/useFocusStyle/index.js.map +0 -1
  323. package/lib/commonjs/components/KeyboardFocusView/hooks/useFocusStyle/useFocusStyle.js +0 -33
  324. package/lib/commonjs/components/KeyboardFocusView/hooks/useFocusStyle/useFocusStyle.js.map +0 -1
  325. package/lib/commonjs/components/KeyboardFocusView/hooks/useFocusStyle/useTintStyle.js +0 -39
  326. package/lib/commonjs/components/KeyboardFocusView/hooks/useFocusStyle/useTintStyle.js.map +0 -1
  327. package/lib/commonjs/components/RenderPropComponent/RenderPropComponent.js +0 -23
  328. package/lib/commonjs/components/RenderPropComponent/RenderPropComponent.js.map +0 -1
  329. package/lib/commonjs/types/BaseKeyboardView.js +0 -18
  330. package/lib/commonjs/types/BaseKeyboardView.js.map +0 -1
  331. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.types.js +0 -4
  332. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.types.js.map +0 -1
  333. package/lib/module/components/KeyboardFocusView/hooks/index.js +0 -4
  334. package/lib/module/components/KeyboardFocusView/hooks/index.js.map +0 -1
  335. package/lib/module/components/KeyboardFocusView/hooks/useFocusStyle/index.js +0 -4
  336. package/lib/module/components/KeyboardFocusView/hooks/useFocusStyle/index.js.map +0 -1
  337. package/lib/module/components/KeyboardFocusView/hooks/useFocusStyle/useFocusStyle.js +0 -28
  338. package/lib/module/components/KeyboardFocusView/hooks/useFocusStyle/useFocusStyle.js.map +0 -1
  339. package/lib/module/components/KeyboardFocusView/hooks/useFocusStyle/useTintStyle.js +0 -34
  340. package/lib/module/components/KeyboardFocusView/hooks/useFocusStyle/useTintStyle.js.map +0 -1
  341. package/lib/module/components/RenderPropComponent/RenderPropComponent.js +0 -17
  342. package/lib/module/components/RenderPropComponent/RenderPropComponent.js.map +0 -1
  343. package/lib/module/types/BaseKeyboardView.js +0 -14
  344. package/lib/module/types/BaseKeyboardView.js.map +0 -1
  345. package/lib/module/types/FocusStyle.js +0 -4
  346. package/lib/module/types/WithKeyboardFocus.js +0 -4
  347. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts +0 -45
  348. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts.map +0 -1
  349. package/lib/typescript/src/components/KeyboardFocusView/hooks/index.d.ts +0 -2
  350. package/lib/typescript/src/components/KeyboardFocusView/hooks/index.d.ts.map +0 -1
  351. package/lib/typescript/src/components/KeyboardFocusView/hooks/useFocusStyle/index.d.ts +0 -2
  352. package/lib/typescript/src/components/KeyboardFocusView/hooks/useFocusStyle/index.d.ts.map +0 -1
  353. package/lib/typescript/src/components/KeyboardFocusView/hooks/useFocusStyle/useFocusStyle.d.ts +0 -175
  354. package/lib/typescript/src/components/KeyboardFocusView/hooks/useFocusStyle/useFocusStyle.d.ts.map +0 -1
  355. package/lib/typescript/src/components/KeyboardFocusView/hooks/useFocusStyle/useTintStyle.d.ts +0 -181
  356. package/lib/typescript/src/components/KeyboardFocusView/hooks/useFocusStyle/useTintStyle.d.ts.map +0 -1
  357. package/lib/typescript/src/components/RenderPropComponent/RenderPropComponent.d.ts +0 -6
  358. package/lib/typescript/src/components/RenderPropComponent/RenderPropComponent.d.ts.map +0 -1
  359. package/lib/typescript/src/types/BaseKeyboardView.d.ts +0 -70
  360. package/lib/typescript/src/types/BaseKeyboardView.d.ts.map +0 -1
  361. package/lib/typescript/src/types/FocusStyle.d.ts +0 -6
  362. package/lib/typescript/src/types/FocusStyle.d.ts.map +0 -1
  363. package/lib/typescript/src/types/WithKeyboardFocus.d.ts +0 -47
  364. package/lib/typescript/src/types/WithKeyboardFocus.d.ts.map +0 -1
  365. package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.ts +0 -73
  366. package/src/components/KeyboardFocusView/hooks/index.ts +0 -1
  367. package/src/components/KeyboardFocusView/hooks/useFocusStyle/index.ts +0 -1
  368. package/src/components/KeyboardFocusView/hooks/useFocusStyle/useFocusStyle.ts +0 -34
  369. package/src/components/KeyboardFocusView/hooks/useFocusStyle/useTintStyle.ts +0 -41
  370. package/src/components/RenderPropComponent/RenderPropComponent.tsx +0 -18
  371. package/src/types/BaseKeyboardView.ts +0 -74
  372. package/src/types/WithKeyboardFocus.ts +0 -115
@@ -1,19 +1,3 @@
1
- buildscript {
2
- // Buildscript is evaluated before everything else so we can't use getExtOrDefault
3
- def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["ExternalKeyboard_kotlinVersion"]
4
-
5
- repositories {
6
- google()
7
- mavenCentral()
8
- }
9
-
10
- dependencies {
11
- classpath "com.android.tools.build:gradle:7.2.1"
12
- // noinspection DifferentKotlinGradleVersion
13
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14
- }
15
- }
16
-
17
1
  def reactNativeArchitectures() {
18
2
  def value = rootProject.getProperties().get("reactNativeArchitectures")
19
3
  return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
@@ -24,8 +8,6 @@ def isNewArchitectureEnabled() {
24
8
  }
25
9
 
26
10
  apply plugin: "com.android.library"
27
- apply plugin: "kotlin-android"
28
-
29
11
 
30
12
  def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
31
13
 
@@ -6,19 +6,19 @@ import com.externalkeyboard.views.ExternalKeyboardLockView.ExternalKeyboardLockV
6
6
  import com.externalkeyboard.views.ExternalKeyboardView.ExternalKeyboardViewManager;
7
7
  import com.externalkeyboard.views.KeyboardFocusGroup.KeyboardFocusGroupManager;
8
8
  import com.externalkeyboard.views.TextInputFocusWrapper.TextInputFocusWrapperManager;
9
- import com.facebook.react.TurboReactPackage;
9
+ import com.facebook.react.BaseReactPackage;
10
10
  import com.facebook.react.bridge.NativeModule;
11
11
  import com.facebook.react.bridge.ReactApplicationContext;
12
12
  import com.facebook.react.module.model.ReactModuleInfo;
13
13
  import com.facebook.react.module.model.ReactModuleInfoProvider;
14
14
  import com.facebook.react.uimanager.ViewManager;
15
15
 
16
- import java.util.ArrayList;
16
+ import java.util.Arrays;
17
17
  import java.util.List;
18
18
  import java.util.HashMap;
19
19
  import java.util.Map;
20
20
 
21
- public class ExternalKeyboardViewPackage extends TurboReactPackage {
21
+ public class ExternalKeyboardViewPackage extends BaseReactPackage {
22
22
  @Override
23
23
  public NativeModule getModule(String name, ReactApplicationContext reactContext) {
24
24
  if (name.equals(ExternalKeyboardModule.NAME)) {
@@ -30,29 +30,31 @@ public class ExternalKeyboardViewPackage extends TurboReactPackage {
30
30
 
31
31
  @Override
32
32
  public ReactModuleInfoProvider getReactModuleInfoProvider() {
33
- return () -> {
34
- Map<String, ReactModuleInfo> map = new HashMap<>();
35
- boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
36
- map.put(ExternalKeyboardModule.NAME, new ReactModuleInfo(ExternalKeyboardModule.NAME, // name
37
- ExternalKeyboardModule.NAME, // className
38
- false, // canOverrideExistingModule
39
- false, // needsEagerInit
40
- true, // hasConstants
41
- false, // isCxxModule
42
- isTurboModule // isTurboModule
43
- ));
44
- return map;
33
+ return new ReactModuleInfoProvider() {
34
+ @Override
35
+ public Map<String, ReactModuleInfo> getReactModuleInfos() {
36
+ Map<String, ReactModuleInfo> map = new HashMap<>();
37
+
38
+ map.put(ExternalKeyboardModule.NAME, new ReactModuleInfo(
39
+ ExternalKeyboardModule.NAME, // name
40
+ ExternalKeyboardModule.NAME, // className
41
+ false, // canOverrideExistingModule
42
+ false, // needsEagerInit
43
+ false, // isCxxModule
44
+ BuildConfig.IS_NEW_ARCHITECTURE_ENABLED // isTurboModule
45
+ ));
46
+ return map;
47
+ }
45
48
  };
46
49
  }
47
50
 
48
51
  @Override
49
52
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
50
- List<ViewManager> viewManagers = new ArrayList<>();
51
- viewManagers.add(new ExternalKeyboardViewManager());
52
- viewManagers.add(new TextInputFocusWrapperManager());
53
- viewManagers.add(new KeyboardFocusGroupManager());
54
- viewManagers.add(new ExternalKeyboardLockViewManager());
55
-
56
- return viewManagers;
53
+ return Arrays.asList(
54
+ new ExternalKeyboardViewManager(),
55
+ new TextInputFocusWrapperManager(),
56
+ new KeyboardFocusGroupManager(),
57
+ new ExternalKeyboardLockViewManager()
58
+ );
57
59
  }
58
60
  }
@@ -2,42 +2,39 @@ package com.externalkeyboard.events;
2
2
 
3
3
  import android.view.KeyEvent;
4
4
 
5
+ import com.externalkeyboard.helper.ReactNativeEventDispatcher;
5
6
  import com.facebook.react.bridge.ReactContext;
6
7
  import com.facebook.react.uimanager.UIManagerHelper;
8
+ import com.facebook.react.uimanager.events.Event;
7
9
  import com.facebook.react.uimanager.events.EventDispatcher;
8
10
 
9
11
  public class EventHelper {
10
12
  public static void focusChanged(ReactContext context, int id, boolean hasFocus) {
11
13
  int surfaceId = UIManagerHelper.getSurfaceId(context);
12
14
  FocusChangeEvent event = new FocusChangeEvent(surfaceId, id, hasFocus);
13
- EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, id);
14
- if (eventDispatcher != null) {
15
- eventDispatcher.dispatchEvent(event);
16
- }
15
+ dispatch(context, id, event);
17
16
  }
18
17
 
19
18
  public static void pressDown(ReactContext context, int id, int keyCode, KeyEvent keyEvent) {
20
19
  int surfaceId = UIManagerHelper.getSurfaceId(context);
21
20
  KeyPressDownEvent keyPressDownEvent = new KeyPressDownEvent(surfaceId, id, keyCode, keyEvent);
22
- EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, id);
23
- if (eventDispatcher != null) {
24
- eventDispatcher.dispatchEvent(keyPressDownEvent);
25
- }
21
+ dispatch(context, id, keyPressDownEvent);
26
22
  }
27
23
 
28
24
  public static void pressUp(ReactContext context, int id, int keyCode, KeyEvent keyEvent, boolean isLongPress) {
29
25
  int surfaceId = UIManagerHelper.getSurfaceId(context);
30
26
  KeyPressUpEvent keyPressUpEvent = new KeyPressUpEvent(surfaceId, id, keyCode, keyEvent, isLongPress);
31
- EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, id);
32
- if (eventDispatcher != null) {
33
- eventDispatcher.dispatchEvent(keyPressUpEvent);
34
- }
27
+ dispatch(context, id, keyPressUpEvent);
35
28
  }
36
29
 
37
30
  public static void multiplyTextSubmit(ReactContext context, int id, String text) {
38
31
  int surfaceId = UIManagerHelper.getSurfaceId(context);
39
32
  MultiplyTextSubmit event = new MultiplyTextSubmit(surfaceId, id, text);
40
- EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, id);
33
+ dispatch(context, id, event);
34
+ }
35
+
36
+ private static void dispatch(ReactContext context, int id, Event<?> event) {
37
+ EventDispatcher eventDispatcher = ReactNativeEventDispatcher.getEventDispatcher(context, id);
41
38
  if (eventDispatcher != null) {
42
39
  eventDispatcher.dispatchEvent(event);
43
40
  }
@@ -8,7 +8,6 @@ import java.util.HashMap;
8
8
  import java.util.Map;
9
9
 
10
10
  import androidx.annotation.Nullable;
11
- import androidx.core.view.ViewCompat;
12
11
 
13
12
  public class FocusHelper {
14
13
  private static final int MASK_FOCUS_UP = 0b1;
@@ -64,7 +63,7 @@ public class FocusHelper {
64
63
  return null;
65
64
  }
66
65
  public static boolean isAccessible(@Nullable View view) {
67
- return view != null && ViewCompat.isImportantForAccessibility(view);
66
+ return view != null && view.isImportantForAccessibility();
68
67
  }
69
68
 
70
69
  public static View findFirstAccessible(@Nullable ViewGroup viewGroup, boolean ignoreRoot) {
@@ -0,0 +1,64 @@
1
+ package com.externalkeyboard.services;
2
+
3
+ import android.view.View;
4
+
5
+ import androidx.annotation.Nullable;
6
+
7
+ import java.lang.ref.WeakReference;
8
+
9
+ /**
10
+ * Remembers the focused view inside an environment and restores it later.
11
+ *
12
+ * Reusable for any "leave then come back" flow — modal presentation, screen
13
+ * navigation, etc. The owner decides <em>when</em> to call store / restore; the
14
+ * only difference between flows is the ordering of those two calls:
15
+ *
16
+ * <pre>
17
+ * Modal: store on present, restore on dismiss.
18
+ * Navigation: store on disappear, restore on appear.
19
+ * </pre>
20
+ *
21
+ * The stored view is held weakly, so it never keeps a detached view alive.
22
+ */
23
+ public class FocusMemoryService {
24
+ private WeakReference<View> storedView = new WeakReference<>(null);
25
+
26
+ /**
27
+ * Captures the currently focused view in the environment's window.
28
+ */
29
+ public void store(@Nullable View environment) {
30
+ if (environment == null) {
31
+ return;
32
+ }
33
+
34
+ storedView = new WeakReference<>(KeyboardFocusService.getFocusedItem(environment));
35
+ }
36
+
37
+ /**
38
+ * Restores focus to the stored view (if any) and clears the stored reference.
39
+ */
40
+ public void restore() {
41
+ View view = storedView.get();
42
+ if (view == null) {
43
+ return;
44
+ }
45
+
46
+ KeyboardFocusService.focus(view);
47
+ storedView.clear();
48
+ }
49
+
50
+ /**
51
+ * Returns the currently stored view without consuming it, or null.
52
+ */
53
+ @Nullable
54
+ public View get() {
55
+ return storedView.get();
56
+ }
57
+
58
+ /**
59
+ * Drops the stored reference without restoring focus.
60
+ */
61
+ public void clean() {
62
+ storedView.clear();
63
+ }
64
+ }
@@ -0,0 +1,41 @@
1
+ package com.externalkeyboard.services;
2
+
3
+ import android.os.Handler;
4
+ import android.os.Looper;
5
+ import android.view.View;
6
+
7
+ import androidx.annotation.Nullable;
8
+
9
+ /**
10
+ * Public entry point for driving the Android focus engine from custom native code.
11
+ * All methods are static — this service holds no state.
12
+ */
13
+ public class KeyboardFocusService {
14
+
15
+ private KeyboardFocusService() {
16
+ }
17
+
18
+ /**
19
+ * Returns the view currently focused within the given environment's window, or null.
20
+ */
21
+ @Nullable
22
+ public static View getFocusedItem(@Nullable View environment) {
23
+ if (environment == null) {
24
+ return null;
25
+ }
26
+
27
+ View root = environment.getRootView();
28
+ return root != null ? root.findFocus() : environment.findFocus();
29
+ }
30
+
31
+ /**
32
+ * Requests focus on the given view on the main thread.
33
+ */
34
+ public static void focus(@Nullable final View view) {
35
+ if (view == null) {
36
+ return;
37
+ }
38
+
39
+ new Handler(Looper.getMainLooper()).post(view::requestFocus);
40
+ }
41
+ }
@@ -1,8 +1,6 @@
1
1
  package com.externalkeyboard.services;
2
2
 
3
3
 
4
- import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
5
-
6
4
  import android.app.Activity;
7
5
  import android.util.Log;
8
6
  import android.view.View;
@@ -11,8 +9,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
11
9
  import com.facebook.react.bridge.UIManager;
12
10
  import com.facebook.react.uimanager.IllegalViewOperationException;
13
11
  import com.facebook.react.uimanager.UIManagerHelper;
14
- import com.facebook.react.uimanager.UIManagerModule;
15
- import com.facebook.react.uimanager.common.ViewUtil;
16
12
 
17
13
  public class KeyboardService {
18
14
  private final ReactApplicationContext context;
@@ -30,17 +26,12 @@ public class KeyboardService {
30
26
 
31
27
  activity.runOnUiThread(() -> {
32
28
  try {
33
- int uiManagerType = ViewUtil.getUIManagerType(tag);
34
- if (uiManagerType == FABRIC) {
35
- UIManager fabricUIManager = UIManagerHelper.getUIManager(context, uiManagerType);
36
- if (fabricUIManager != null) {
37
- View view = fabricUIManager.resolveView(tag);
29
+ UIManager uiManager = UIManagerHelper.getUIManagerForReactTag(context, tag);
30
+ if (uiManager != null) {
31
+ View view = uiManager.resolveView(tag);
32
+ if (view != null) {
38
33
  view.requestFocus();
39
34
  }
40
- } else {
41
- UIManager uiManager = context.getNativeModule(UIManagerModule.class);
42
- View view = uiManager.resolveView(tag);
43
- view.requestFocus();
44
35
  }
45
36
  } catch (IllegalViewOperationException error) {
46
37
  Log.e("KEYBOARD_FOCUS_ERROR", error.getMessage());
@@ -2,7 +2,6 @@ package com.externalkeyboard.views.ExternalKeyboardView;
2
2
 
3
3
  import android.content.Context;
4
4
  import android.view.KeyEvent;
5
- import android.view.ViewGroup;
6
5
 
7
6
  import com.externalkeyboard.views.base.keyboard.ViewKeyHandlerBase;
8
7
 
@@ -14,6 +13,8 @@ public class ExternalKeyboardView extends ViewKeyHandlerBase {
14
13
 
15
14
  @Override
16
15
  public boolean dispatchKeyEvent(KeyEvent keyEvent) {
16
+ this.handleKeyPress(keyEvent);
17
+
17
18
  if (this.isFocusLocked(keyEvent)) {
18
19
  return true;
19
20
  }
@@ -25,13 +26,6 @@ public class ExternalKeyboardView extends ViewKeyHandlerBase {
25
26
  return super.dispatchKeyEvent(keyEvent);
26
27
  }
27
28
 
28
- this.handleKeyPress(keyEvent);
29
-
30
29
  return super.dispatchKeyEvent(keyEvent);
31
30
  }
32
-
33
- public void setCanBeFocused(boolean canBeFocused) {
34
- int descendantFocusability = canBeFocused ? ViewGroup.FOCUS_BEFORE_DESCENDANTS : ViewGroup.FOCUS_BLOCK_DESCENDANTS;
35
- this.setDescendantFocusability(descendantFocusability);
36
- }
37
31
  }
@@ -69,14 +69,6 @@ public class ExternalKeyboardViewManager extends com.externalkeyboard.ExternalKe
69
69
  wrapper.setCanBeFocused(canBeFocused);
70
70
  }
71
71
 
72
- @Override
73
- @ReactProp(name = "enableA11yFocus", defaultBoolean = false)
74
- public void setEnableA11yFocus(ExternalKeyboardView wrapper, boolean enableA11yFocus) {
75
- if(wrapper.enableA11yFocus != enableA11yFocus) {
76
- wrapper.enableA11yFocus = enableA11yFocus;
77
- }
78
- }
79
-
80
72
  @Override
81
73
  @ReactProp(name = "screenAutoA11yFocus", defaultBoolean = false)
82
74
  public void setScreenAutoA11yFocus(ExternalKeyboardView wrapper, boolean enableA11yFocus) {
@@ -146,6 +138,12 @@ public class ExternalKeyboardViewManager extends com.externalkeyboard.ExternalKe
146
138
  //stub
147
139
  }
148
140
 
141
+ @Override
142
+ @ReactProp(name = "roundedHaloFix")
143
+ public void setRoundedHaloFix(ExternalKeyboardView view, boolean value) {
144
+ //stub
145
+ }
146
+
149
147
  @Override
150
148
  @ReactProp(name = "tintColor")
151
149
  public void setTintColor(ExternalKeyboardView view, @Nullable Integer value) {
@@ -248,8 +246,9 @@ public class ExternalKeyboardViewManager extends com.externalkeyboard.ExternalKe
248
246
  }
249
247
 
250
248
  @Override
251
- public void setGroup(ExternalKeyboardView view, boolean value) {
252
- //stub
249
+ @ReactProp(name = "focusableWrapper", defaultBoolean = false)
250
+ public void setFocusableWrapper(ExternalKeyboardView view, boolean value) {
251
+ view.setFocusableWrapper(value);
253
252
  }
254
253
 
255
254
  @Override
@@ -258,14 +257,22 @@ public class ExternalKeyboardViewManager extends com.externalkeyboard.ExternalKe
258
257
  }
259
258
 
260
259
  @Override
261
- public void focus(ExternalKeyboardView view) {
260
+ public void rnekKeyboardFocus(ExternalKeyboardView view) {
262
261
  view.focus();
263
262
  }
264
263
 
264
+ @Override
265
+ public void rnekScreenReaderFocus(ExternalKeyboardView view) {
266
+ view.a11yFocus();
267
+ }
268
+
269
+
265
270
  @Override
266
271
  public void receiveCommand(ReactViewGroup root, String commandId, @Nullable ReadableArray args) {
267
- if (commandId.equals("focus")) {
268
- this.focus((ExternalKeyboardView) root);
272
+ if (commandId.equals("rnekKeyboardFocus")) {
273
+ this.rnekKeyboardFocus((ExternalKeyboardView) root);
274
+ } else if (commandId.equals("rnekScreenReaderFocus")) {
275
+ this.rnekScreenReaderFocus((ExternalKeyboardView) root);
269
276
  } else {
270
277
  super.receiveCommand(root, commandId, args);
271
278
  }
@@ -7,6 +7,7 @@ import android.text.Editable;
7
7
  import android.view.KeyEvent;
8
8
  import android.view.MotionEvent;
9
9
  import android.view.View;
10
+ import android.view.inputmethod.InputMethodManager;
10
11
  import android.widget.EditText;
11
12
 
12
13
  import androidx.annotation.NonNull;
@@ -32,6 +33,13 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
32
33
  private boolean blurOnSubmit = true;
33
34
  private boolean multiline = false;
34
35
  private boolean keyboardFocusable = true;
36
+ // FOCUS_BY_PRESS only: set while a directional focus search (Tab/Shift+Tab/arrows)
37
+ // is moving focus out of the EditText, so the blur handler knows not to pull
38
+ // focus back to the wrapper. Cleared right after on the message queue.
39
+ private boolean navigatingAway = false;
40
+ // FOCUS_BY_PRESS only: set when Enter enters edit mode, so the EditText key listener
41
+ // swallows the single paired Enter key-up that would otherwise hide the IME hint.
42
+ private boolean consumeActivationEnterUp = false;
35
43
 
36
44
  private static boolean resolveIsNativelyFixedVersion() {
37
45
  try {
@@ -62,7 +70,16 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
62
70
  private void updateFocusability() {
63
71
  this.setFocusable(shouldWrapperBeFocusable());
64
72
  if (this.reactEditText != null) {
65
- this.reactEditText.setFocusable(shouldEditTextBeFocusable());
73
+ boolean editTextFocusable = shouldEditTextBeFocusable();
74
+ this.reactEditText.setFocusable(editTextFocusable);
75
+ if (focusType == FOCUS_BY_PRESS) {
76
+ // RN creates every ReactEditText with focusableInTouchMode=true, so in touch
77
+ // mode the EditText stays a focus candidate even with focusable=false. During
78
+ // navigation focus would land on the field (flashing the soft keyboard) before
79
+ // resolving to the wrapper. Clear it so focus goes straight to the wrapper;
80
+ // handleTextInputFocus restores it when the user enters edit mode.
81
+ this.reactEditText.setFocusableInTouchMode(editTextFocusable);
82
+ }
66
83
  }
67
84
  }
68
85
 
@@ -135,9 +152,10 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
135
152
  focusabilityListener = new View.OnAttachStateChangeListener() {
136
153
  @Override
137
154
  public void onViewAttachedToWindow(@NonNull View view) {
138
- // Re-apply focusability after React Native attaches the view; the
139
- // framework may reset it during the layout/commit phase.
140
- view.setFocusable(shouldEditTextBeFocusable());
155
+ // Re-apply focusability (both focusable and focusableInTouchMode) after
156
+ // React Native attaches the view; the framework may reset them during the
157
+ // layout/commit phase.
158
+ updateFocusability();
141
159
  }
142
160
  @Override
143
161
  public void onViewDetachedFromWindow(@NonNull View view) {}
@@ -172,7 +190,14 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
172
190
  if (!hasTextEditFocus) {
173
191
  updateFocusability();
174
192
  if (focusType == FOCUS_BY_PRESS) {
175
- post(() -> TextInputFocusWrapper.this.requestFocus());
193
+ // Tab/Shift+Tab/arrows blur the EditText as part of moving focus to
194
+ // another view — leave it there. Otherwise edit mode was exited in
195
+ // place (Enter/submit, keyboard dismissed), and clearFocus() would let
196
+ // the framework default focus to the first view on screen, so pull
197
+ // focus back to the wrapper to stay on this control in its idle state.
198
+ if (!navigatingAway) {
199
+ post(() -> TextInputFocusWrapper.this.requestFocus());
200
+ }
176
201
  }
177
202
  }
178
203
  });
@@ -241,13 +266,29 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
241
266
  if (focusType == FOCUS_BY_PRESS && this.reactEditText != null) {
242
267
  this.reactEditText.setFocusable(false);
243
268
  }
244
- if (keyCode == KeyEvent.KEYCODE_SPACE || keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
269
+ // Only activate from the wrapper's idle state (wrapper itself focused). While the
270
+ // EditText is editing it — not the wrapper — holds focus, so an Enter that bubbles
271
+ // up here must fall through to submit/blur instead of re-entering edit mode.
272
+ if (isActivationKey(keyCode) && this.isFocused()) {
273
+ if (keyCode == KeyEvent.KEYCODE_ENTER) {
274
+ // Focus is about to move to the EditText; the paired Enter key-up will land on
275
+ // it and ReactEditText.onKeyUp(Enter) would hide the soft-input hint we just
276
+ // raised (a visible blink). Mark it so the EditText key listener swallows that
277
+ // one key-up.
278
+ consumeActivationEnterUp = true;
279
+ }
245
280
  this.handleTextInputFocus();
246
281
  return true;
247
282
  }
248
283
  return super.onKeyDown(keyCode, event);
249
284
  }
250
285
 
286
+ private boolean isActivationKey(int keyCode) {
287
+ return keyCode == KeyEvent.KEYCODE_SPACE
288
+ || keyCode == KeyEvent.KEYCODE_DPAD_CENTER
289
+ || keyCode == KeyEvent.KEYCODE_ENTER;
290
+ }
291
+
251
292
  // --- Touch handling ---
252
293
 
253
294
  @Override
@@ -281,6 +322,27 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
281
322
  return super.focusSearch(direction);
282
323
  }
283
324
 
325
+ @Override
326
+ public View focusSearch(View focused, int direction) {
327
+ // Called when a descendant (the EditText, in edit mode) drives a directional
328
+ // focus search. Flag it so the blur handler lets focus move to the next view
329
+ // instead of pulling it back to the wrapper. Cleared on the next loop tick so
330
+ // a search that finds no target (no blur fired) doesn't strand the flag.
331
+ View next = super.focusSearch(focused, direction);
332
+ if (focusType == FOCUS_BY_PRESS) {
333
+ navigatingAway = true;
334
+ post(() -> navigatingAway = false);
335
+ // Dismiss the IME up front (only when there's actually somewhere to go) so it
336
+ // hides together with the focus move instead of flashing after the blur. The
337
+ // destination is an idle wrapper, not an edit field, and Android won't auto-
338
+ // hide the keyboard when focus leaves an EditText for a plain focusable View.
339
+ if (next != null && next != focused && this.reactEditText != null) {
340
+ hideSoftKeyboard(this.reactEditText);
341
+ }
342
+ }
343
+ return next;
344
+ }
345
+
284
346
  @Override
285
347
  public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
286
348
  if (focusType != FOCUS_BY_PRESS) {
@@ -299,21 +361,36 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
299
361
 
300
362
  private void onMultiplyBlurSubmitHandle() {
301
363
  if (this.reactEditText == null) return;
302
- if (this.multiline) {
303
- this.reactEditText.setOnKeyListener((v, keyCode, event) -> {
304
- if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER && !event.isShiftPressed()) {
305
- Editable editableText = reactEditText.getText();
306
- String text = editableText == null ? "" : String.valueOf(editableText);
307
- EventHelper.multiplyTextSubmit((ReactContext) context, getId(), text);
308
- if (blurOnSubmit && v instanceof EditText) {
309
- v.clearFocus();
310
- return true;
311
- }
364
+ this.reactEditText.setOnKeyListener((v, keyCode, event) -> {
365
+ // Swallow the single Enter key-up that immediately follows entering edit mode,
366
+ // so ReactEditText.onKeyUp doesn't hide the freshly raised soft-input hint.
367
+ // Runs before the EditText's own onKeyUp, so returning true suppresses the hide.
368
+ if (consumeActivationEnterUp && event.getAction() == KeyEvent.ACTION_UP
369
+ && keyCode == KeyEvent.KEYCODE_ENTER) {
370
+ consumeActivationEnterUp = false;
371
+ return true;
372
+ }
373
+ if (this.multiline && event.getAction() == KeyEvent.ACTION_DOWN
374
+ && keyCode == KeyEvent.KEYCODE_ENTER && !event.isShiftPressed()) {
375
+ Editable editableText = reactEditText.getText();
376
+ String text = editableText == null ? "" : String.valueOf(editableText);
377
+ EventHelper.multiplyTextSubmit((ReactContext) context, getId(), text);
378
+ if (blurOnSubmit && v instanceof EditText) {
379
+ v.clearFocus();
380
+ return true;
312
381
  }
313
- return false;
314
- });
315
- } else {
316
- this.reactEditText.setOnKeyListener(null);
382
+ }
383
+ return false;
384
+ });
385
+ }
386
+
387
+ private void hideSoftKeyboard(View view) {
388
+ try {
389
+ InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
390
+ if (imm != null) {
391
+ imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
392
+ }
393
+ } catch (Exception ignored) {
317
394
  }
318
395
  }
319
396
 
@@ -322,7 +399,8 @@ public class TextInputFocusWrapper extends FocusHighlightBase implements View.On
322
399
  this.setFocusable(false);
323
400
  this.reactEditText.setFocusable(true);
324
401
  // focusableInTouchMode is required for requestFocus() to succeed when the device
325
- // is in touch mode (canTakeFocus() returns false without it).
402
+ // is in touch mode (canTakeFocus() returns false without it), and re-arms the
403
+ // EditText as a focus target after updateFocusability cleared it for navigation.
326
404
  this.reactEditText.setFocusableInTouchMode(true);
327
405
  if (!this.reactEditText.hasFocus()) {
328
406
  this.reactEditText.requestFocusFromJS();
@@ -163,6 +163,11 @@ public class TextInputFocusWrapperManager extends com.externalkeyboard.TextInput
163
163
  view.setKeyboardFocusable(value);
164
164
  }
165
165
 
166
+ @Override
167
+ public void setHasOnFocusChanged(TextInputFocusWrapper view, boolean value) {
168
+ //stub - Android attaches focus listeners unconditionally
169
+ }
170
+
166
171
  @Override
167
172
  @ReactProp(name = "haloEffect", defaultBoolean = true)
168
173
  public void setHaloEffect(TextInputFocusWrapper view, boolean value) {
@@ -218,4 +223,10 @@ public class TextInputFocusWrapperManager extends com.externalkeyboard.TextInput
218
223
  public void setHaloCornerRadius(TextInputFocusWrapper view, float value) {
219
224
 
220
225
  }
226
+
227
+ @Override
228
+ @ReactProp(name = "roundedHaloFix")
229
+ public void setRoundedHaloFix(TextInputFocusWrapper view, boolean value) {
230
+
231
+ }
221
232
  }
@@ -6,21 +6,27 @@ import android.view.View;
6
6
 
7
7
  public class FocusHighlightBase extends ViewOrderGroupBase {
8
8
  protected boolean focusHighlight = true;
9
+ protected boolean focusableWrapper = true;
9
10
 
10
11
  public void setFocusHighlight (boolean defaultFocusHighlightEnabled) {
11
12
  focusHighlight = defaultFocusHighlightEnabled;
12
13
  syncFocusHighlight();
13
14
  }
14
15
 
15
- protected View getFocusHighlightView () {
16
- return this.getFirstChild();
16
+ public void setFocusableWrapper (boolean isFocusableWrapper) {
17
+ focusableWrapper = isFocusableWrapper;
18
+ syncFocusHighlight();
19
+ }
20
+
21
+ protected View getFocusTargetView () {
22
+ return focusableWrapper ? this.getFirstChild() : this;
17
23
  }
18
24
 
19
25
  protected void syncFocusHighlight () {
20
26
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
21
- View child = this.getFocusHighlightView();
22
- if(child != null) {
23
- child.setDefaultFocusHighlightEnabled(focusHighlight);
27
+ View view = getFocusTargetView();
28
+ if(view != null) {
29
+ view.setDefaultFocusHighlightEnabled(focusHighlight);
24
30
  }
25
31
  }
26
32
  }