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
@@ -10,10 +10,11 @@
10
10
  #import "RNCEKVCustomFocusEffectProtocol.h"
11
11
  #import "RCTViewComponentView+RNCEKVExternalKeyboard.h"
12
12
  #import "RNCEKVCustomGroudIdProtocol.h"
13
+ #import "RNCEKVFocusProtocol.h"
14
+ #import "RNCEKVHaloProtocol.h"
13
15
 
14
16
  @implementation RNCEKVViewClass (RNCEKVExternalKeyboard)
15
17
 
16
-
17
18
  - (NSString *)focusGroupIdentifier {
18
19
  if ([self.superview conformsToProtocol:@protocol(RNCEKVCustomGroudIdProtocol)]) {
19
20
  id<RNCEKVCustomGroudIdProtocol> parent = (id<RNCEKVCustomGroudIdProtocol>)self.superview;
@@ -22,12 +23,12 @@
22
23
  return groupId;
23
24
  }
24
25
  }
25
-
26
+
26
27
  return [super focusGroupIdentifier];
27
28
  }
28
29
 
29
30
 
30
- - (UIFocusEffect*)focusEffect {
31
+ - (UIFocusEffect*)focusEffect API_AVAILABLE(ios(15.0)) {
31
32
  if ([self.superview conformsToProtocol:@protocol(RNCEKVCustomFocusEffectProtocol)]) {
32
33
  id<RNCEKVCustomFocusEffectProtocol> parent = (id<RNCEKVCustomFocusEffectProtocol>)self.superview;
33
34
  UIFocusEffect* effect = [parent customFocusEffect];
@@ -35,9 +36,20 @@
35
36
  return effect;
36
37
  }
37
38
  }
38
-
39
+
39
40
  return [super focusEffect];
40
41
  }
41
42
 
43
+ - (BOOL)canBecomeFocused {
44
+ if ([self.superview conformsToProtocol:@protocol(RNCEKVFocusProtocol)]) {
45
+ id<RNCEKVFocusProtocol> parent = (id<RNCEKVFocusProtocol>)self.superview;
46
+ if (parent.focusableWrapper) {
47
+ return parent.canBeFocused;
48
+ }
49
+ }
50
+
51
+ return [super canBecomeFocused];
52
+ }
53
+
42
54
  @end
43
55
 
@@ -16,8 +16,15 @@
16
16
 
17
17
  static char kCustomFocusViewKey;
18
18
 
19
+ static void RNCEKVUIViewControllerSwizzle(void) {
20
+ RNCEKVSwizzleInstanceMethod([UIViewController class], @selector(viewDidAppear:), @selector(keyboardedViewDidAppear:));
21
+ RNCEKVSwizzleInstanceMethod([UIViewController class], @selector(preferredFocusEnvironments), @selector(keyboardedPreferredFocusEnvironments));
22
+ }
23
+
19
24
  @implementation UIViewController (RNCEKVExternalKeyboard)
20
25
 
26
+ RNCEKV_INSTALL_SWIZZLES(RNCEKVUIViewControllerSwizzle)
27
+
21
28
  - (UIView *)rncekvCustomFocusView {
22
29
  return objc_getAssociatedObject(self, &kCustomFocusViewKey);
23
30
  }
@@ -26,16 +33,6 @@ static char kCustomFocusViewKey;
26
33
  objc_setAssociatedObject(self, &kCustomFocusViewKey, customFocusView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
27
34
  }
28
35
 
29
- + (void)load
30
- {
31
- static dispatch_once_t once_token;
32
-
33
- dispatch_once(&once_token, ^{
34
- RNCEKVSwizzleInstanceMethod([self class], @selector(viewDidAppear:), @selector(keyboardedViewDidAppear:));
35
- RNCEKVSwizzleInstanceMethod([self class], @selector(preferredFocusEnvironments), @selector(keyboardedPreferredFocusEnvironments));
36
- });
37
- }
38
-
39
36
  - (void)keyboardedViewDidAppear:(BOOL)animated {
40
37
  [self keyboardedViewDidAppear:animated];
41
38
  [[NSNotificationCenter defaultCenter] postNotificationName:@"ViewControllerChangedNotification" object:self];
@@ -45,6 +45,7 @@ struct HaloProps {
45
45
  double haloExpendY{0};
46
46
  double haloCornerRadius{0};
47
47
  facebook::react::SharedColor tintColor{};
48
+ bool roundedHaloFix{false};
48
49
 
49
50
  template <typename T>
50
51
  static HaloProps from(const T &props) {
@@ -54,6 +55,7 @@ struct HaloProps {
54
55
  props.haloExpendY,
55
56
  props.haloCornerRadius,
56
57
  props.tintColor,
58
+ props.roundedHaloFix,
57
59
  };
58
60
  }
59
61
  };
@@ -96,13 +98,11 @@ struct ContextMenuProps {
96
98
 
97
99
  struct AutoFocusProps {
98
100
  bool autoFocus{false};
99
- bool enableA11yFocus{false};
100
-
101
+
101
102
  template <typename T>
102
103
  static AutoFocusProps from(const T &props) {
103
104
  return AutoFocusProps{
104
105
  props.autoFocus,
105
- props.enableA11yFocus,
106
106
  };
107
107
  }
108
108
  };
@@ -110,7 +110,7 @@ struct AutoFocusProps {
110
110
  struct KeyPressProps {
111
111
  bool hasKeyDownPress{false};
112
112
  bool hasKeyUpPress{false};
113
-
113
+
114
114
  template <typename T>
115
115
  static KeyPressProps from(const T &props) {
116
116
  return KeyPressProps{
@@ -13,4 +13,23 @@
13
13
 
14
14
  void RNCEKVSwizzleInstanceMethod(Class swizzleClass, SEL originalSelector, SEL swizzledSelector);
15
15
 
16
+ #define RNCEKV_CONCAT_INNER(a, b) a##b
17
+ #define RNCEKV_CONCAT(a, b) RNCEKV_CONCAT_INNER(a, b)
18
+
19
+ #ifdef RCT_DYNAMIC_FRAMEWORKS
20
+
21
+ #define RNCEKV_INSTALL_SWIZZLES(registerFn) \
22
+ __attribute__((constructor)) \
23
+ static void RNCEKV_CONCAT(RNCEKVInstall_, registerFn)(void) { registerFn(); }
24
+
25
+ #else
26
+
27
+ #define RNCEKV_INSTALL_SWIZZLES(registerFn) \
28
+ + (void)load { \
29
+ static dispatch_once_t RNCEKV_CONCAT(once_, registerFn); \
30
+ dispatch_once(&RNCEKV_CONCAT(once_, registerFn), ^{ registerFn(); }); \
31
+ }
32
+
33
+ #endif
34
+
16
35
  #endif /* RNCEKVSwizzleInstanceMethod_h */
@@ -9,7 +9,7 @@
9
9
  #define RNCEKVCustomFocusEffectProtocol_h
10
10
 
11
11
  @protocol RNCEKVCustomFocusEffectProtocol <NSObject>
12
- - (UIFocusEffect*)customFocusEffect;
12
+ - (UIFocusEffect*)customFocusEffect API_AVAILABLE(ios(15.0));
13
13
  @end
14
14
 
15
15
  #endif /* RNCEKVCustomFocusEffectProtocol_h */
@@ -0,0 +1,39 @@
1
+ //
2
+ // RNCEKVFocusMemoryService.h
3
+ // react-native-external-keyboard
4
+ //
5
+ // Created by Artur Kalach on 05/06/2026.
6
+ //
7
+
8
+ #ifndef RNCEKVFocusMemoryService_h
9
+ #define RNCEKVFocusMemoryService_h
10
+
11
+ #import <UIKit/UIKit.h>
12
+
13
+ /// Remembers the focused view inside a focus environment and restores it later.
14
+ ///
15
+ /// Reusable for any "leave then come back" flow — modal presentation, screen
16
+ /// navigation, etc. The owner decides *when* to call store / restore; the only
17
+ /// difference between flows is the ordering of those two calls:
18
+ ///
19
+ /// Modal: store on present, restore on dismiss.
20
+ /// Navigation: store on disappear, restore on appear.
21
+ ///
22
+ /// The stored view is held weakly, so it never keeps a detached view alive.
23
+ @interface RNCEKVFocusMemoryService : NSObject
24
+
25
+ /// Captures the currently focused view in the environment and marks it preferred.
26
+ - (void)store:(id<UIFocusEnvironment>)environment;
27
+
28
+ /// Restores focus to the stored view (if any) and clears the stored reference.
29
+ - (void)restore;
30
+
31
+ /// Returns the currently stored view without consuming it, or nil.
32
+ - (UIView *)get;
33
+
34
+ /// Drops the stored reference without restoring focus.
35
+ - (void)clean;
36
+
37
+ @end
38
+
39
+ #endif /* RNCEKVFocusMemoryService_h */
@@ -0,0 +1,42 @@
1
+ //
2
+ // RNCEKVFocusMemoryService.mm
3
+ // react-native-external-keyboard
4
+ //
5
+ // Created by Artur Kalach on 05/06/2026.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "RNCEKVFocusMemoryService.h"
10
+ #import "RNCEKVKeyboardFocusService.h"
11
+
12
+ @implementation RNCEKVFocusMemoryService {
13
+ __weak UIView *_storedView;
14
+ }
15
+
16
+ - (void)store:(id<UIFocusEnvironment>)environment {
17
+ if (!environment) {
18
+ return;
19
+ }
20
+
21
+ _storedView = [RNCEKVKeyboardFocusService getFocusedItem:environment];
22
+ [RNCEKVKeyboardFocusService updatePreferredFocusEnvironment:_storedView];
23
+ }
24
+
25
+ - (void)restore {
26
+ if (!_storedView) {
27
+ return;
28
+ }
29
+
30
+ [RNCEKVKeyboardFocusService focus:_storedView];
31
+ _storedView = nil;
32
+ }
33
+
34
+ - (UIView *)get {
35
+ return _storedView;
36
+ }
37
+
38
+ - (void)clean {
39
+ _storedView = nil;
40
+ }
41
+
42
+ @end
@@ -0,0 +1,28 @@
1
+ //
2
+ // RNCEKVKeyboardFocusService.h
3
+ // react-native-external-keyboard
4
+ //
5
+ // Created by Artur Kalach on 05/06/2026.
6
+ //
7
+
8
+ #ifndef RNCEKVKeyboardFocusService_h
9
+ #define RNCEKVKeyboardFocusService_h
10
+
11
+ #import <UIKit/UIKit.h>
12
+
13
+ /// Public entry point for driving the UIKit focus engine from custom native code.
14
+ /// All methods are static — this service holds no state.
15
+ @interface RNCEKVKeyboardFocusService : NSObject
16
+
17
+ /// Returns the view currently focused inside the given focus environment, or nil.
18
+ + (UIView *)getFocusedItem:(id<UIFocusEnvironment>)environment;
19
+
20
+ /// Marks a view as the preferred focus environment without forcing a focus update.
21
+ + (void)updatePreferredFocusEnvironment:(UIView *)view;
22
+
23
+ /// Moves keyboard focus to the given view on the next focus update.
24
+ + (void)focus:(UIView *)view;
25
+
26
+ @end
27
+
28
+ #endif /* RNCEKVKeyboardFocusService_h */
@@ -0,0 +1,54 @@
1
+ //
2
+ // RNCEKVKeyboardFocusService.mm
3
+ // react-native-external-keyboard
4
+ //
5
+ // Created by Artur Kalach on 05/06/2026.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "RNCEKVKeyboardFocusService.h"
10
+ #import "UIViewController+RNCEKVExternalKeyboard.h"
11
+ #import <React/RCTUtils.h>
12
+
13
+ @implementation RNCEKVKeyboardFocusService
14
+
15
+ + (UIView *)getFocusedItem:(id<UIFocusEnvironment>)environment {
16
+ if (!environment) {
17
+ return nil;
18
+ }
19
+
20
+ @try {
21
+ UIFocusSystem *focusSystem = [UIFocusSystem focusSystemForEnvironment:environment];
22
+ if (![focusSystem.focusedItem isKindOfClass:[UIView class]]) {
23
+ return nil;
24
+ }
25
+
26
+ return (UIView *)focusSystem.focusedItem;
27
+ } @catch (NSException *exception) {
28
+ return nil;
29
+ }
30
+ }
31
+
32
+ + (void)updatePreferredFocusEnvironment:(UIView *)view {
33
+ if (!view) {
34
+ return;
35
+ }
36
+
37
+ UIWindow *window = RCTKeyWindow();
38
+ if (window && window.rootViewController) {
39
+ window.rootViewController.rncekvCustomFocusView = view;
40
+ }
41
+ }
42
+
43
+ + (void)focus:(UIView *)view {
44
+ if (!view) {
45
+ return;
46
+ }
47
+
48
+ UIWindow *window = RCTKeyWindow();
49
+ if (window && window.rootViewController) {
50
+ [window.rootViewController rncekvFocusView:view];
51
+ }
52
+ }
53
+
54
+ @end
@@ -31,6 +31,8 @@ newProps:(const RNCEKV::FocusProps &)newProps;
31
31
 
32
32
  - (void)onFocusChangeHandler:(BOOL)isFocused;
33
33
 
34
+ - (NSNumber *)resolveFocusChange:(UIFocusUpdateContext *)context;
35
+
34
36
  @end
35
37
 
36
38
 
@@ -20,10 +20,6 @@
20
20
  NSNumber* _isFocused;
21
21
  }
22
22
 
23
- - (BOOL)isGroup {
24
- return false;
25
- }
26
-
27
23
  - (BOOL)isKeyboardFocused {
28
24
  return [_isFocused isEqual:@YES];
29
25
  }
@@ -33,7 +29,7 @@
33
29
  _focusDelegate = [[RNCEKVFocusDelegate alloc] initWithView:self];
34
30
  _isFocused = nil;
35
31
  }
36
-
32
+
37
33
  return self;
38
34
  }
39
35
 
@@ -50,15 +46,21 @@
50
46
 
51
47
 
52
48
  - (BOOL)canBecomeFocused {
53
- if (!_canBeFocused)
54
- NO;
55
- return [_focusDelegate canBecomeFocused];
49
+ if (!self.focusableWrapper) {
50
+ return _canBeFocused;
51
+ }
52
+
53
+ return [super canBecomeFocused];
56
54
  }
57
55
 
58
56
 
57
+ - (NSNumber *)resolveFocusChange:(UIFocusUpdateContext *)context {
58
+ return [_focusDelegate isFocusChanged:context];
59
+ }
60
+
59
61
  - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
60
62
  withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
61
- _isFocused = [_focusDelegate isFocusChanged:context];
63
+ _isFocused = [self resolveFocusChange:context];
62
64
 
63
65
  if ([self hasOnFocusChanged]) {
64
66
  if (_isFocused != nil) {
@@ -76,7 +78,7 @@
76
78
  if (_canBeFocused != newProps.canBeFocused) {
77
79
  [self setCanBeFocused:newProps.canBeFocused];
78
80
  }
79
-
81
+
80
82
  if (_hasOnFocusChanged != newProps.hasOnFocusChanged) {
81
83
  [self setHasOnFocusChanged:newProps.hasOnFocusChanged];
82
84
  }
@@ -18,7 +18,6 @@
18
18
  @interface RNCEKVViewFocusRequestBase : RNCEKVViewContextMenuBase
19
19
 
20
20
  @property BOOL autoFocus;
21
- @property BOOL enableA11yFocus;
22
21
 
23
22
 
24
23
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -28,6 +27,7 @@ newProps:(const RNCEKV::AutoFocusProps &)newProps;
28
27
  #endif
29
28
 
30
29
  - (void)focus;
30
+ - (void)screenReaderFocus;
31
31
 
32
32
  @end
33
33
 
@@ -19,13 +19,11 @@
19
19
  @implementation RNCEKVViewFocusRequestBase {
20
20
  BOOL _isAttachedToWindow;
21
21
  BOOL _autoFocusRequested;
22
- BOOL _enableA11yFocus;
23
22
  }
24
23
 
25
24
  - (void)cleanReferences {
26
25
  [super cleanReferences];
27
26
  _isAttachedToWindow = NO;
28
- _enableA11yFocus = NO;
29
27
  _autoFocusRequested = NO;
30
28
  }
31
29
 
@@ -39,14 +37,17 @@
39
37
  }
40
38
 
41
39
  - (void)focus {
42
-
43
40
  UIViewController *controller = self.reactViewController;
44
41
  if (controller != nil) {
45
42
  [controller rncekvFocusView: self];
46
43
  }
47
-
44
+ }
45
+
46
+ - (void)screenReaderFocus {
48
47
  dispatch_async(dispatch_get_main_queue(), ^{
49
- [self a11yFocus];
48
+ UIView *focusView = [self getFocusTargetView];
49
+ UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification,
50
+ focusView);
50
51
  });
51
52
  }
52
53
 
@@ -56,10 +57,6 @@ newProps:(const RNCEKV::AutoFocusProps &)newProps {
56
57
  if (oldProps.autoFocus != newProps.autoFocus) {
57
58
  [self setAutoFocus: newProps.autoFocus];
58
59
  }
59
-
60
- if (_enableA11yFocus != newProps.enableA11yFocus) {
61
- [self setEnableA11yFocus: newProps.enableA11yFocus];
62
- }
63
60
  }
64
61
 
65
62
 
@@ -71,14 +68,6 @@ newProps:(const RNCEKV::AutoFocusProps &)newProps {
71
68
  [self focusOnMount];
72
69
  }
73
70
 
74
- - (void)a11yFocus {
75
- if (!_enableA11yFocus)
76
- return;
77
- UIView *focusView = [self getFocusTargetView];
78
- UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification,
79
- focusView);
80
- }
81
-
82
71
  - (void)focusOnMount {
83
72
  if (self.autoFocus) {
84
73
  if(!_autoFocusRequested) {
@@ -22,6 +22,7 @@
22
22
  @property (nonatomic, assign) CGFloat haloExpendX;
23
23
  @property (nonatomic, assign) CGFloat haloExpendY;
24
24
  @property (nonatomic, assign) BOOL isHaloHidden;
25
+ @property (nonatomic, assign) BOOL roundedHaloFix;
25
26
 
26
27
  #ifdef RCT_NEW_ARCH_ENABLED
27
28
  - (void)updateHaloProps:(const RNCEKV::HaloProps &)oldProps
@@ -10,12 +10,31 @@
10
10
  #import "RNCEKVHaloDelegate.h"
11
11
  #import "RNCEKVExternalKeyboardHalloBase.h"
12
12
 
13
+ // See CLAUDE.md in this directory for the full rationale (RN's cornerRadius
14
+ // toggle, the pinned custom halo, the delayed re-arm and loop guard).
15
+
13
16
  #ifdef RCT_NEW_ARCH_ENABLED
14
17
  #import <React/RCTConversions.h>
18
+
19
+ // invalidateLayer is private to RCTViewComponentView; forward-declare so the
20
+ // override and its [super] call compile cleanly.
21
+ @interface RNCEKVBaseViewClass (RNCEKVInvalidateLayer)
22
+ - (void)invalidateLayer;
23
+ @end
15
24
  #endif
16
25
 
26
+ // Delay before re-arming, to win UIKit's same-pass default halo (see CLAUDE.md).
27
+ static const NSTimeInterval RNCEKVHaloRearmDelay = 0.02;
28
+
17
29
  @implementation RNCEKVExternalKeyboardHalloBase {
18
30
  RNCEKVHaloDelegate *_haloDelegate;
31
+ BOOL _rearmScheduled; // a flush is already pending
32
+ // Dedup signature — re-arm only when one of these changed (breaks the loop).
33
+ CGRect _lastArmedBounds;
34
+ CGFloat _lastArmedRadius;
35
+ BOOL _lastArmedFocused;
36
+ CGFloat _stableLayerRadius; // last non-zero cornerRadius (RN toggles it to 0)
37
+ BOOL _forceRearm; // a halo prop changed — re-arm even if geometry didn't
19
38
  }
20
39
 
21
40
  - (instancetype)initWithFrame:(CGRect)frame
@@ -23,7 +42,7 @@
23
42
  if (self = [super initWithFrame:frame]) {
24
43
  _haloDelegate = [[RNCEKVHaloDelegate alloc] initWithView:self];
25
44
  }
26
-
45
+
27
46
  return self;
28
47
  }
29
48
 
@@ -31,37 +50,154 @@
31
50
  return _haloDelegate.focusEffect;
32
51
  }
33
52
 
53
+ - (UIFocusEffect*)focusEffect API_AVAILABLE(ios(15.0)) {
54
+ // Hidden views must return our empty effect even when wrapper, or the system
55
+ // default ring leaks through (see CLAUDE.md).
56
+ if (!self.focusableWrapper || self.isHaloHidden) {
57
+ UIFocusEffect* effect = [self customFocusEffect];
58
+ if(effect != nil) {
59
+ return effect;
60
+ }
61
+ }
62
+
63
+ return [super focusEffect];
64
+ }
65
+
66
+
67
+
68
+ - (void)layoutSubviews {
69
+ [super layoutSubviews];
70
+
71
+ if(!self.isHaloHidden && !self.roundedHaloFix) return;
72
+
73
+ [self observeStableRadius];
74
+ [self setNeedsHaloRearm];
75
+ }
76
+
77
+ - (UIView *)rearmTarget {
78
+ return (self.focusableWrapper && self.subviews.count > 0)
79
+ ? self.subviews.firstObject
80
+ : self;
81
+ }
82
+
83
+ // Cache the last non-zero corner radius so the delegate pins the halo to it,
84
+ // not to the transient 0 RN sets mid-pass (see CLAUDE.md).
85
+ - (void)observeStableRadius {
86
+ CGFloat radius = [self getFocusTargetView].layer.cornerRadius;
87
+ if (radius > 0) {
88
+ _stableLayerRadius = radius;
89
+ [_haloDelegate observeCornerRadius:radius];
90
+ }
91
+ }
92
+
93
+ // Coalesce a burst of passes into one delayed re-arm (see CLAUDE.md).
94
+ - (void)setNeedsHaloRearm {
95
+ if (_rearmScheduled) return;
96
+ _rearmScheduled = YES;
97
+
98
+ __weak __typeof(self) weakSelf = self;
99
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(RNCEKVHaloRearmDelay * NSEC_PER_SEC)),
100
+ dispatch_get_main_queue(), ^{
101
+ [weakSelf flushHaloRearm];
102
+ });
103
+ }
104
+
105
+ - (void)flushHaloRearm {
106
+ _rearmScheduled = NO;
107
+
108
+ UIView *target = [self rearmTarget];
109
+ BOOL focused = target.isFocused;
110
+
111
+ // The halo only renders on the focused view; skip the rest otherwise.
112
+ if (!focused) {
113
+ _lastArmedFocused = NO;
114
+ return;
115
+ }
116
+
117
+ // Skip when the signature is unchanged — this is what stops the re-arm from
118
+ // feeding itself (see CLAUDE.md). Key on the stable radius, never the live one.
119
+ CGRect bounds = target.bounds;
120
+ CGFloat radius = _stableLayerRadius;
121
+ if (!_forceRearm &&
122
+ _lastArmedFocused &&
123
+ CGRectEqualToRect(bounds, _lastArmedBounds) &&
124
+ radius == _lastArmedRadius) {
125
+ return;
126
+ }
127
+
128
+ _forceRearm = NO;
129
+ _lastArmedBounds = bounds;
130
+ _lastArmedRadius = radius;
131
+ _lastArmedFocused = YES;
132
+
133
+ // Re-arm: read focusEffect and write it back to force UIKit to repaint.
134
+ if (@available(iOS 15.0, *)) {
135
+ target.focusEffect = target.focusEffect;
136
+ }
137
+ }
138
+
34
139
  - (void)cleanReferences {
35
140
  [super cleanReferences];
36
141
  [_haloDelegate clear];
142
+ _rearmScheduled = NO;
143
+ _lastArmedBounds = CGRectZero;
144
+ _lastArmedRadius = 0;
145
+ _lastArmedFocused = NO;
146
+ _stableLayerRadius = 0;
147
+ _forceRearm = NO;
37
148
  _isHaloHidden = false;
38
149
  _haloExpendX = 0;
39
150
  _haloExpendY = 0;
40
151
  _haloCornerRadius = 0;
152
+ _roundedHaloFix = false;
41
153
  }
42
154
 
43
155
 
156
+ // A halo prop changed: force a re-arm even if geometry didn't move (see CLAUDE.md).
157
+ - (void)haloAppearanceChanged {
158
+ [_haloDelegate invalidate];
159
+ _forceRearm = YES;
160
+ [self setNeedsHaloRearm];
161
+ }
162
+
44
163
  - (void)setIsHaloHidden:(BOOL)isHaloHidden {
45
164
  _isHaloHidden = isHaloHidden;
46
- [_haloDelegate invalidate];
165
+ [self haloAppearanceChanged];
47
166
  }
48
167
 
49
168
  - (void)setHaloCornerRadius:(CGFloat)haloCornerRadius {
50
169
  _haloCornerRadius = haloCornerRadius;
51
- [_haloDelegate invalidate];
170
+ [self haloAppearanceChanged];
52
171
  }
53
172
 
54
173
  - (void)setHaloExpendX:(CGFloat)haloExpendX {
55
174
  _haloExpendX = haloExpendX;
56
- [_haloDelegate invalidate];
175
+ [self haloAppearanceChanged];
57
176
  }
58
177
 
59
178
  - (void)setHaloExpendY:(CGFloat)haloExpendY {
60
179
  _haloExpendY = haloExpendY;
61
- [_haloDelegate invalidate];
180
+ [self haloAppearanceChanged];
181
+ }
182
+
183
+ - (void)setRoundedHaloFix:(BOOL)roundedHaloFix {
184
+ _roundedHaloFix = roundedHaloFix;
185
+ [self haloAppearanceChanged];
62
186
  }
63
187
 
64
188
  #ifdef RCT_NEW_ARCH_ENABLED
189
+
190
+
191
+ - (void)invalidateLayer {
192
+ [super invalidateLayer]; // must run first — RN sets the layer here
193
+
194
+ if (!self.isHaloHidden && !self.roundedHaloFix) return;
195
+
196
+ // Catches the cornerRadius/style repaints layoutSubviews doesn't (see CLAUDE.md).
197
+ [self observeStableRadius];
198
+ [self setNeedsHaloRearm];
199
+ }
200
+
65
201
  - (void)updateHaloProps:(const RNCEKV::HaloProps &)oldProps
66
202
  newProps:(const RNCEKV::HaloProps &)newProps {
67
203
  if (_isHaloHidden == newProps.haloEffect) {
@@ -79,7 +215,11 @@
79
215
  if (oldProps.haloCornerRadius != newProps.haloCornerRadius) {
80
216
  [self setHaloCornerRadius:newProps.haloCornerRadius];
81
217
  }
82
-
218
+
219
+ if (self.roundedHaloFix != newProps.roundedHaloFix) {
220
+ [self setRoundedHaloFix:newProps.roundedHaloFix];
221
+ }
222
+
83
223
  UIColor *newColor = RCTUIColorFromSharedColor(newProps.tintColor);
84
224
  BOOL renewColor = newColor != nil && self.tintColor == nil;
85
225
  BOOL isColorChanged = oldProps.tintColor != newProps.tintColor;
@@ -27,6 +27,8 @@ NS_ASSUME_NONNULL_BEGIN
27
27
  - (void)onSubviewRemoved:(UIView *)subview;
28
28
  - (void)onSubviewsLayoutUpdated;
29
29
 
30
+ - (BOOL)focusableWrapper;
31
+
30
32
  - (void)cleanReferences;
31
33
 
32
34
  @end