react-native-external-keyboard 0.8.5 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/README.md +149 -67
  2. package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegate.java +81 -75
  3. package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegateHost.java +14 -0
  4. package/android/src/main/java/com/externalkeyboard/helper/Linking/A11yOrderLinking.java +5 -0
  5. package/android/src/main/java/com/externalkeyboard/modules/ExternalKeyboardModule.java +10 -10
  6. package/android/src/main/java/com/externalkeyboard/services/FocusLinkObserver/FocusLinkObserver.java +26 -35
  7. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardLockView/ExternalKeyboardLockView.java +5 -0
  8. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardLockView/ExternalKeyboardLockViewManager.java +6 -0
  9. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardView.java +8 -307
  10. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardViewManager.java +11 -18
  11. package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapper.java +208 -101
  12. package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapperManager.java +123 -34
  13. package/android/src/main/java/com/externalkeyboard/views/base/FocusHighlightBase.java +38 -0
  14. package/android/src/main/java/com/externalkeyboard/views/base/ViewGroupBase.java +19 -0
  15. package/android/src/main/java/com/externalkeyboard/views/base/ViewOrderGroupBase.java +190 -0
  16. package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewFocusChangeBase.java +39 -0
  17. package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewFocusRequestBase.java +125 -0
  18. package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewKeyHandlerBase.java +40 -0
  19. package/android/src/newarch/TextInputFocusWrapperManagerSpec.java +2 -8
  20. package/android/src/oldarch/ExternalKeyboardLockViewManagerSpec.java +1 -0
  21. package/android/src/oldarch/TextInputFocusWrapperManagerSpec.java +32 -2
  22. package/ios/Delegates/RNCEKVFocusLinkDelegate/RNCEKVFocusLinkDelegate.h +35 -0
  23. package/ios/Delegates/RNCEKVFocusLinkDelegate/RNCEKVFocusLinkDelegate.mm +195 -0
  24. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderProtocol.h +6 -8
  25. package/ios/Delegates/RNCEKVFocusSequenceDelegate/RNCEKVFocusSequenceDelegate.h +25 -0
  26. package/ios/Delegates/RNCEKVFocusSequenceDelegate/RNCEKVFocusSequenceDelegate.mm +163 -0
  27. package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.h +2 -6
  28. package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.mm +6 -78
  29. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.h +3 -4
  30. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.mm +32 -101
  31. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloProtocol.h +1 -1
  32. package/ios/Extensions/RCTEnhancedScrollView+RNCEKVExternalKeyboard.mm +1 -1
  33. package/ios/Extensions/RCTTextInputComponentView+RNCEKVExternalKeyboard.mm +15 -0
  34. package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.h +9 -6
  35. package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.mm +16 -29
  36. package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.h +1 -0
  37. package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.mm +8 -0
  38. package/ios/Helpers/RNCEKVNativeProps/RNCEKVNativeProps.h +123 -0
  39. package/ios/Protocols/RNCEKVCustomFocusEffectProtocol.h +15 -0
  40. package/ios/Protocols/RNCEKVCustomGroudIdProtocol.h +15 -0
  41. package/ios/Protocols/RNCEKVKeyboardFocusableProtocol.h +15 -0
  42. package/ios/Services/RNCEKVFocusLinkObserver.mm +2 -3
  43. package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVOrderRelationship/RNCEKVOrderRelationship.mm +15 -28
  44. package/ios/Services/RNCEKVOrderLinking.mm +43 -51
  45. package/ios/Views/Base/ContextMenu/RNCEKVViewContextMenuBase.h +33 -0
  46. package/ios/Views/Base/ContextMenu/RNCEKVViewContextMenuBase.mm +84 -0
  47. package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.h +37 -0
  48. package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.mm +89 -0
  49. package/ios/Views/Base/FocusOrderGroup/RNCEKVViewOrderGroupBase.h +49 -0
  50. package/ios/Views/Base/FocusOrderGroup/RNCEKVViewOrderGroupBase.mm +245 -0
  51. package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.h +34 -0
  52. package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.mm +112 -0
  53. package/ios/Views/Base/GroupIdentifier/RNCEKVViewGroupIdentifierBase.h +27 -0
  54. package/ios/Views/Base/GroupIdentifier/RNCEKVViewGroupIdentifierBase.mm +69 -0
  55. package/ios/Views/Base/KeyPress/RNCEKVViewKeyPress.h +30 -0
  56. package/ios/Views/Base/KeyPress/RNCEKVViewKeyPress.mm +75 -0
  57. package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.h +33 -0
  58. package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.mm +92 -0
  59. package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.h +36 -0
  60. package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.mm +63 -0
  61. package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockView.h +8 -0
  62. package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockView.mm +105 -2
  63. package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockViewManager.mm +11 -0
  64. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.h +7 -82
  65. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.mm +23 -493
  66. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.mm +5 -7
  67. package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.mm +20 -17
  68. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.h +10 -39
  69. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.mm +40 -73
  70. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapperManager.mm +76 -8
  71. package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js +35 -7
  72. package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
  73. package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js +79 -1
  74. package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
  75. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.js +18 -4
  76. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.js.map +1 -1
  77. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +17 -2
  78. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -1
  79. package/lib/commonjs/components/KeyboardFocusView/KeyboardFocusView.js +2 -0
  80. package/lib/commonjs/components/KeyboardFocusView/KeyboardFocusView.js.map +1 -1
  81. package/lib/commonjs/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -0
  82. package/lib/commonjs/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
  83. package/lib/commonjs/utils/useFocusStyle.js +3 -9
  84. package/lib/commonjs/utils/useFocusStyle.js.map +1 -1
  85. package/lib/commonjs/utils/withKeyboardFocus.js +32 -15
  86. package/lib/commonjs/utils/withKeyboardFocus.js.map +1 -1
  87. package/lib/commonjs/utils/wrapOrderPrefix.js +17 -0
  88. package/lib/commonjs/utils/wrapOrderPrefix.js.map +1 -0
  89. package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js +35 -7
  90. package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
  91. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js +80 -2
  92. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
  93. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.js +18 -4
  94. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.js.map +1 -1
  95. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +16 -2
  96. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -1
  97. package/lib/module/components/KeyboardFocusView/KeyboardFocusView.js +2 -0
  98. package/lib/module/components/KeyboardFocusView/KeyboardFocusView.js.map +1 -1
  99. package/lib/module/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -0
  100. package/lib/module/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
  101. package/lib/module/utils/useFocusStyle.js +4 -10
  102. package/lib/module/utils/useFocusStyle.js.map +1 -1
  103. package/lib/module/utils/withKeyboardFocus.js +32 -15
  104. package/lib/module/utils/withKeyboardFocus.js.map +1 -1
  105. package/lib/module/utils/wrapOrderPrefix.js +12 -0
  106. package/lib/module/utils/wrapOrderPrefix.js.map +1 -0
  107. package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts.map +1 -1
  108. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.d.ts.map +1 -1
  109. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts +15 -0
  110. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts.map +1 -1
  111. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts +1 -1
  112. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts.map +1 -1
  113. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts +2 -1
  114. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts.map +1 -1
  115. package/lib/typescript/src/components/KeyboardFocusView/KeyboardFocusView.d.ts.map +1 -1
  116. package/lib/typescript/src/index.d.ts +1 -1
  117. package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts +1 -0
  118. package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts.map +1 -1
  119. package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts +16 -1
  120. package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts.map +1 -1
  121. package/lib/typescript/src/types/BaseKeyboardView.d.ts +2 -0
  122. package/lib/typescript/src/types/BaseKeyboardView.d.ts.map +1 -1
  123. package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts +1 -0
  124. package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts.map +1 -1
  125. package/lib/typescript/src/types/WithKeyboardFocus.d.ts +11 -2
  126. package/lib/typescript/src/types/WithKeyboardFocus.d.ts.map +1 -1
  127. package/lib/typescript/src/utils/useFocusStyle.d.ts +1 -0
  128. package/lib/typescript/src/utils/useFocusStyle.d.ts.map +1 -1
  129. package/lib/typescript/src/utils/withKeyboardFocus.d.ts.map +1 -1
  130. package/lib/typescript/src/utils/wrapOrderPrefix.d.ts +9 -0
  131. package/lib/typescript/src/utils/wrapOrderPrefix.d.ts.map +1 -0
  132. package/package.json +6 -2
  133. package/src/components/BaseKeyboardView/BaseKeyboardView.tsx +88 -10
  134. package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.tsx +138 -2
  135. package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.ts +15 -0
  136. package/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.tsx +21 -4
  137. package/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.tsx +20 -3
  138. package/src/components/KeyboardFocusView/KeyboardFocusView.tsx +2 -0
  139. package/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -0
  140. package/src/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
  141. package/src/types/BaseKeyboardView.ts +2 -0
  142. package/src/types/KeyboardFocusLock.types.ts +1 -0
  143. package/src/types/WithKeyboardFocus.ts +19 -2
  144. package/src/utils/useFocusStyle.tsx +5 -15
  145. package/src/utils/withKeyboardFocus.tsx +44 -15
  146. package/src/utils/wrapOrderPrefix.ts +16 -0
  147. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusGuideDelegate/RNCEKVFocusGuideDelegate.h +0 -36
  148. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusGuideDelegate/RNCEKVFocusGuideDelegate.mm +0 -150
  149. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.h +0 -47
  150. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.mm +0 -326
  151. package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVKeyboardOrderManager.h +0 -17
  152. package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVKeyboardOrderManager.mm +0 -15
  153. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js +0 -22
  154. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js.map +0 -1
  155. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js +0 -17
  156. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js.map +0 -1
  157. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.d.ts +0 -4
  158. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.d.ts.map +0 -1
  159. package/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.tsx +0 -16
@@ -1,5 +1,6 @@
1
1
  package com.externalkeyboard.services.FocusLinkObserver;
2
2
 
3
+ import android.util.Log;
3
4
  import android.view.View;
4
5
 
5
6
  import java.lang.ref.WeakReference;
@@ -9,7 +10,7 @@ import java.util.List;
9
10
  import java.util.Map;
10
11
 
11
12
  public class FocusLinkObserver {
12
- private final Map<String, View> links;
13
+ private final Map<String, WeakReference<View>> links;
13
14
  private final Map<String, List<Subscriber>> subscribers;
14
15
 
15
16
  public FocusLinkObserver() {
@@ -22,16 +23,16 @@ public class FocusLinkObserver {
22
23
  throw new IllegalArgumentException("Both id and link are required");
23
24
  }
24
25
 
25
- links.put(id, link);
26
+ links.entrySet().removeIf(e -> e.getValue().get() == null);
27
+ links.put(id, new WeakReference<>(link));
26
28
  emitLinkUpdated(id, link);
27
29
  }
28
30
 
29
-
30
31
  public void emitRemove(String id) {
31
32
  if (links.containsKey(id)) {
32
- links.remove(id); // Remove the link
33
- emitLinkRemoved(id); // Notify subscribers
34
- subscribers.remove(id); // Clean up subscribers for the ID
33
+ links.remove(id);
34
+ emitLinkRemoved(id);
35
+ subscribers.remove(id);
35
36
  }
36
37
  }
37
38
 
@@ -44,7 +45,11 @@ public class FocusLinkObserver {
44
45
  subscribers.get(id).add(new Subscriber(onLinkUpdated, onLinkRemoved));
45
46
 
46
47
  if (onLinkUpdated != null && links.containsKey(id)) {
47
- onLinkUpdated.onLinkUpdated(links.get(id));
48
+ WeakReference<View> ref = links.get(id);
49
+ View link = ref != null ? ref.get() : null;
50
+ if (link != null) {
51
+ onLinkUpdated.onLinkUpdated(link);
52
+ }
48
53
  }
49
54
  }
50
55
 
@@ -55,11 +60,9 @@ public class FocusLinkObserver {
55
60
 
56
61
  List<Subscriber> subscriberList = subscribers.get(id);
57
62
  if (subscriberList != null) {
58
- subscriberList.removeIf(subscriber -> {
59
- LinkUpdatedCallback updatedCallback = subscriber.onLinkUpdated.get();
60
- LinkRemovedCallback removedCallback = subscriber.onLinkRemoved.get();
61
- return updatedCallback == onLinkUpdated && removedCallback == onLinkRemoved;
62
- });
63
+ subscriberList.removeIf(subscriber ->
64
+ subscriber.onLinkUpdated == onLinkUpdated && subscriber.onLinkRemoved == onLinkRemoved
65
+ );
63
66
 
64
67
  if (subscriberList.isEmpty()) {
65
68
  subscribers.remove(id);
@@ -70,8 +73,6 @@ public class FocusLinkObserver {
70
73
  private void emitLinkUpdated(String id, View link) {
71
74
  List<Subscriber> subscriberList = subscribers.get(id);
72
75
  if (subscriberList != null) {
73
- subscriberList.removeIf(Subscriber::isEmpty);
74
-
75
76
  for (Subscriber subscriber : subscriberList) {
76
77
  subscriber.notifyLinkUpdated(link);
77
78
  }
@@ -81,10 +82,6 @@ public class FocusLinkObserver {
81
82
  private void emitLinkRemoved(String id) {
82
83
  List<Subscriber> subscriberList = subscribers.get(id);
83
84
  if (subscriberList != null) {
84
- // Remove stale subscribers (whose weak references were garbage-collected)
85
- subscriberList.removeIf(Subscriber::isEmpty);
86
-
87
- // Notify all valid subscribers
88
85
  for (Subscriber subscriber : subscriberList) {
89
86
  subscriber.notifyLinkRemoved();
90
87
  }
@@ -102,30 +99,24 @@ public class FocusLinkObserver {
102
99
  }
103
100
 
104
101
  private static class Subscriber {
105
- private final WeakReference<LinkUpdatedCallback> onLinkUpdated;
106
- private final WeakReference<LinkRemovedCallback> onLinkRemoved;
102
+ final LinkUpdatedCallback onLinkUpdated;
103
+ final LinkRemovedCallback onLinkRemoved;
107
104
 
108
- public Subscriber(LinkUpdatedCallback onLinkUpdated, LinkRemovedCallback onLinkRemoved) {
109
- this.onLinkUpdated = new WeakReference<>(onLinkUpdated);
110
- this.onLinkRemoved = new WeakReference<>(onLinkRemoved);
105
+ Subscriber(LinkUpdatedCallback onLinkUpdated, LinkRemovedCallback onLinkRemoved) {
106
+ this.onLinkUpdated = onLinkUpdated;
107
+ this.onLinkRemoved = onLinkRemoved;
111
108
  }
112
109
 
113
- public void notifyLinkUpdated(View link) {
114
- LinkUpdatedCallback callback = onLinkUpdated.get();
115
- if (callback != null) {
116
- callback.onLinkUpdated(link);
110
+ void notifyLinkUpdated(View link) {
111
+ if (onLinkUpdated != null) {
112
+ onLinkUpdated.onLinkUpdated(link);
117
113
  }
118
114
  }
119
115
 
120
- public void notifyLinkRemoved() {
121
- LinkRemovedCallback callback = onLinkRemoved.get();
122
- if (callback != null) {
123
- callback.onLinkRemoved();
116
+ void notifyLinkRemoved() {
117
+ if (onLinkRemoved != null) {
118
+ onLinkRemoved.onLinkRemoved();
124
119
  }
125
120
  }
126
-
127
- public boolean isEmpty() {
128
- return onLinkUpdated.get() == null && onLinkRemoved.get() == null;
129
- }
130
121
  }
131
122
  }
@@ -11,6 +11,7 @@ import com.facebook.react.views.view.ReactViewGroup;
11
11
  public class ExternalKeyboardLockView extends ReactViewGroup {
12
12
  private int componentType;
13
13
  private Boolean lockDisable = false;
14
+ private Boolean forceLock = false;
14
15
 
15
16
  public ExternalKeyboardLockView(Context context) {
16
17
  super(context);
@@ -35,6 +36,10 @@ public class ExternalKeyboardLockView extends ReactViewGroup {
35
36
  this.lockDisable = lockDisabled;
36
37
  }
37
38
 
39
+ public void setForceLock(boolean forceLock) {
40
+ this.forceLock = forceLock;
41
+ }
42
+
38
43
  @Override
39
44
  public View focusSearch(View focused, int direction) {
40
45
  try {
@@ -29,4 +29,10 @@ public class ExternalKeyboardLockViewManager extends com.externalkeyboard.Extern
29
29
  public void setLockDisabled(ExternalKeyboardLockView view, boolean value) {
30
30
  view.setLockDisabled(value);
31
31
  }
32
+
33
+ @Override
34
+ @ReactProp(name = "forceLock")
35
+ public void setForceLock(ExternalKeyboardLockView view, boolean value) {
36
+ view.setForceLock(value);
37
+ }
32
38
  }
@@ -1,336 +1,37 @@
1
1
  package com.externalkeyboard.views.ExternalKeyboardView;
2
2
 
3
3
  import android.content.Context;
4
- import android.view.FocusFinder;
5
4
  import android.view.KeyEvent;
6
- import android.view.View;
7
5
  import android.view.ViewGroup;
8
- import android.view.ViewTreeObserver;
9
- import android.view.accessibility.AccessibilityEvent;
10
6
 
11
- import com.externalkeyboard.delegates.FocusOrderDelegate;
12
- import com.externalkeyboard.events.EventHelper;
7
+ import com.externalkeyboard.views.base.keyboard.ViewKeyHandlerBase;
13
8
 
14
- import com.externalkeyboard.helper.FocusHelper;
15
- import com.externalkeyboard.helper.ReactNativeVersionChecker;
16
- import com.externalkeyboard.services.KeyboardKeyPressHandler;
17
- import com.facebook.react.bridge.ReactContext;
18
- import com.facebook.react.uimanager.UIManagerHelper;
19
- import com.facebook.react.uimanager.common.ViewUtil;
20
- import com.facebook.react.uimanager.events.Event;
21
- import com.facebook.react.uimanager.events.EventDispatcher;
22
- import com.facebook.react.uimanager.events.EventDispatcherListener;
23
- import com.facebook.react.views.view.ReactViewGroup;
24
-
25
- public class ExternalKeyboardView extends ReactViewGroup {
26
- public boolean hasKeyDownListener = false;
27
- public boolean hasKeyUpListener = false;
28
- public boolean autoFocus = false;
29
- public boolean hasBeenFocused = false;
30
- public boolean hasBeenA11yFocused = false;
31
- public boolean enableA11yFocus = false;
32
- public boolean screenAutoA11yFocus = false;
33
- public int screenAutoA11yFocusDelay = 500;
34
- public int lockFocus = 0;
35
- public String orderForward;
36
- public String orderBackward;
37
- public String orderId;
38
-
39
-
40
- private FocusOrderDelegate focusOrderDelegate = null;
41
- private EventDispatcher a11yViewAppearDispatcher = null;
42
- private EventDispatcherListener eventA11yViewAppearListener = null;
43
- private final KeyboardKeyPressHandler keyboardKeyPressHandler;
44
- private final Context context;
45
- private View listeningView;
46
-
47
- private Integer orderIndex;
48
- private String orderGroup;
49
- private View firstChild;
50
-
51
- private String orderUp;
52
- private String orderDown;
53
- private String orderLeft;
54
-
55
- public String getOrderRight() {
56
- return orderRight;
57
- }
58
-
59
- public void setOrderRight(String orderRight) {
60
- focusOrderDelegate.refreshRight(this.orderRight, orderRight);
61
- this.orderRight = orderRight;
62
- }
63
-
64
- public String getOrderLeft() {
65
- return orderLeft;
66
- }
67
-
68
- public void setOrderLeft(String orderLeft) {
69
- focusOrderDelegate.refreshLeft(this.orderLeft, orderLeft);
70
- this.orderLeft = orderLeft;
71
- }
72
-
73
- public String getOrderDown() {
74
- return orderDown;
75
- }
76
-
77
- public void setOrderDown(String orderDown) {
78
- focusOrderDelegate.refreshDown(this.orderDown, orderDown);
79
- this.orderDown = orderDown;
80
- }
81
-
82
- public String getOrderUp() {
83
- return orderUp;
84
- }
85
-
86
- public void setOrderUp(String orderUp) {
87
- focusOrderDelegate.refreshUp(this.orderUp, orderUp);
88
- this.orderUp = orderUp;
89
- }
90
-
91
- private String orderRight;
9
+ public class ExternalKeyboardView extends ViewKeyHandlerBase {
92
10
 
93
11
  public ExternalKeyboardView(Context context) {
94
12
  super(context);
95
- this.context = context;
96
- this.focusOrderDelegate = new FocusOrderDelegate(this);
97
- this.keyboardKeyPressHandler = new KeyboardKeyPressHandler();
98
- }
99
-
100
- public View getFirstChild() {
101
- return this.firstChild;
102
- }
103
-
104
- public String getOrderGroup() {
105
- return this.orderGroup;
106
- }
107
-
108
- public String getOrderId() {
109
- return this.orderId;
110
- }
111
-
112
- public void setOrderGroup(String orderGroup) {
113
- focusOrderDelegate.updateOrderGroup(this.orderGroup, orderGroup);
114
- this.orderGroup = orderGroup;
115
- }
116
-
117
- public Integer getOrderIndex() {
118
- return this.orderIndex;
119
- }
120
-
121
- public void setOrderIndex(int orderIndex) {
122
- if (this.orderIndex == null) {
123
- this.orderIndex = orderIndex;
124
- } else {
125
- this.orderIndex = orderIndex;
126
- focusOrderDelegate.refreshOrder();
127
- }
128
- }
129
-
130
- public void linkAddView(View child) {
131
- if (firstChild == null) {
132
- firstChild = child;
133
- focusOrderDelegate.link();
134
- }
135
- }
136
-
137
- public void linkRemoveView(View view) {
138
- if (view == firstChild) {
139
- firstChild = null;
140
- focusOrderDelegate.unlink(view);
141
- }
142
- }
143
-
144
- @Override
145
- public View focusSearch(View focused, int direction) {
146
- if (lockFocus == 0 && orderGroup == null && orderIndex == null && orderForward == null && orderBackward == null) {
147
- return super.focusSearch(focused, direction);
148
- }
149
-
150
- boolean isLocked = FocusHelper.isLocked(direction, lockFocus);
151
- if (isLocked) {
152
- return this;
153
- }
154
-
155
- if (direction == FOCUS_FORWARD && orderForward != null) {
156
- View nextView = this.focusOrderDelegate.getLink(orderForward);
157
- if (isValidLinkedFocusTarget(nextView)) {
158
- return nextView;
159
- }
160
- }
161
-
162
- if (direction == FOCUS_BACKWARD && orderBackward != null) {
163
- View prevView = this.focusOrderDelegate.getLink(orderBackward);
164
- if (isValidLinkedFocusTarget(prevView)) {
165
- return prevView;
166
- }
167
- }
168
-
169
- if (ReactNativeVersionChecker.isReactNative80OrLater()) {
170
- if (orderGroup != null && orderIndex != null && (direction == FOCUS_FORWARD || direction == FOCUS_BACKWARD)) {
171
- return FocusFinder.getInstance().findNextFocus((ViewGroup) this.getParent(), focused, direction);
172
- }
173
- }
174
-
175
- return super.focusSearch(focused, direction);
176
13
  }
177
14
 
178
15
  @Override
179
16
  public boolean dispatchKeyEvent(KeyEvent keyEvent) {
180
- if(lockFocus != 0) {
181
- int keyCode = keyEvent.getKeyCode();
182
- boolean isLocked = FocusHelper.isKeyLocked(keyCode, lockFocus);
183
- if(isLocked) {
184
- return true;
185
- }
17
+ if (this.isFocusLocked(keyEvent)) {
18
+ return true;
186
19
  }
187
- if (!this.hasKeyUpListener && !this.hasKeyDownListener) {
20
+ if (!this.hasKeyListener()) {
188
21
  return super.dispatchKeyEvent(keyEvent);
189
22
  }
190
23
 
191
- int keyCode = keyEvent.getKeyCode();
192
- if (keyCode == KeyEvent.KEYCODE_TAB) {
193
- return super.dispatchKeyEvent(keyEvent); //?
24
+ if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_TAB) {
25
+ return super.dispatchKeyEvent(keyEvent);
194
26
  }
195
27
 
196
- KeyboardKeyPressHandler.PressInfo pressInfo = keyboardKeyPressHandler.getEventsFromKeyPress(keyCode, keyEvent);
197
-
198
- if (pressInfo.firePressDownEvent && this.hasKeyDownListener) {
199
- EventHelper.pressDown((ReactContext) context, this.getId(), keyCode, keyEvent);
200
- }
201
-
202
- if (pressInfo.firePressUpEvent && this.hasKeyUpListener) {
203
- EventHelper.pressUp((ReactContext) context, this.getId(), keyCode, keyEvent, pressInfo.isLongPress);
204
- }
28
+ this.handleKeyPress(keyEvent);
205
29
 
206
30
  return super.dispatchKeyEvent(keyEvent);
207
31
  }
208
32
 
209
- @Override
210
- protected void onAttachedToWindow() {
211
- super.onAttachedToWindow();
212
-
213
- this.listeningView = getFocusingView();
214
- setFocusable(this.listeningView == this);
215
-
216
- this.listeningView.setOnFocusChangeListener((focusedView, hasFocus) -> {
217
- EventHelper.focusChanged((ReactContext) context, this.getId(), hasFocus);
218
- });
219
-
220
- if (autoFocus && !hasBeenFocused) {
221
- this.autoFocusOnDraw();
222
- hasBeenFocused = true;
223
- }
224
- }
225
-
226
- private void onRnScreenViewAppear() {
227
- boolean a11yAutoFocus = autoFocus && enableA11yFocus && !hasBeenA11yFocused && screenAutoA11yFocus;
228
- if (!a11yAutoFocus) return;
229
-
230
- try {
231
- int reactTag = this.getId();
232
- int uiManagerType = ViewUtil.getUIManagerType(reactTag);
233
- a11yViewAppearDispatcher = UIManagerHelper.getEventDispatcher((ReactContext) context, uiManagerType);
234
- if (a11yViewAppearDispatcher == null) return;
235
- View focusingView = this.getFocusingView();
236
-
237
-
238
- eventA11yViewAppearListener = new EventDispatcherListener() {
239
- @Override
240
- public void onEventDispatch(Event event) {
241
- if ("topClick".equals(event.getEventName())) {
242
- a11yViewAppearDispatcher.removeListener(this);
243
- eventA11yViewAppearListener = null;
244
- hasBeenA11yFocused = true;
245
- }
246
- if ("topFinishTransitioning".equals(event.getEventName()) || "topShow".equals(event.getEventName())) {
247
- if (hasBeenA11yFocused) return;
248
- hasBeenA11yFocused = true;
249
-
250
- focusingView.postDelayed(() -> {
251
- focus(false, true);
252
- a11yViewAppearDispatcher.removeListener(this);
253
- eventA11yViewAppearListener = null;
254
- }, screenAutoA11yFocusDelay);
255
- }
256
- }
257
- };
258
- a11yViewAppearDispatcher.addListener(eventA11yViewAppearListener);
259
- } catch (Exception ignored) {
260
- }
261
- }
262
-
263
- private void autoFocusOnDraw() {
264
- getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
265
- @Override
266
- public boolean onPreDraw() {
267
- onRnScreenViewAppear();
268
- getViewTreeObserver().removeOnPreDrawListener(this);
269
- focus();
270
-
271
- return true;
272
- }
273
- });
274
- }
275
-
276
- @Override
277
- protected void onDetachedFromWindow() {
278
- super.onDetachedFromWindow();
279
- if (this.a11yViewAppearDispatcher != null && this.eventA11yViewAppearListener != null) {
280
- this.a11yViewAppearDispatcher.removeListener(this.eventA11yViewAppearListener);
281
- eventA11yViewAppearListener = null;
282
- }
283
- if (this.listeningView != null) {
284
- this.listeningView.setOnFocusChangeListener(null);
285
- }
286
-
287
- // this.focusOrderDelegate.clear(firstChild); // ToDO check how to clean
288
- }
289
-
290
- private View getFocusingView() {
291
- View focusableView = FocusHelper.getFocusableView(this);
292
- return focusableView != null ? focusableView : this;
293
- }
294
-
295
- private boolean isValidLinkedFocusTarget(View target) {
296
- if (target == null || !target.isAttachedToWindow() || !this.isAttachedToWindow()) {
297
- return false;
298
- }
299
-
300
- if (target.getWindowToken() == null || this.getWindowToken() == null) {
301
- return false;
302
- }
303
-
304
- if (target.getWindowToken() != this.getWindowToken()) {
305
- return false;
306
- }
307
-
308
- return target.getRootView() == this.getRootView();
309
- }
310
-
311
33
  public void setCanBeFocused(boolean canBeFocused) {
312
34
  int descendantFocusability = canBeFocused ? ViewGroup.FOCUS_BEFORE_DESCENDANTS : ViewGroup.FOCUS_BLOCK_DESCENDANTS;
313
35
  this.setDescendantFocusability(descendantFocusability);
314
36
  }
315
-
316
- private void a11yFocus(View view) {
317
- if (!enableA11yFocus) return;
318
- view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
319
- }
320
-
321
-
322
- public void focus(Boolean keyboard, Boolean a11y) {
323
- View focusingView = this.getFocusingView();
324
- if (keyboard) {
325
- focusingView.requestFocus();
326
- }
327
- if (a11y) {
328
- a11yFocus(focusingView);
329
- }
330
- }
331
-
332
- public void focus() {
333
- this.focus(true, true);
334
- }
335
-
336
37
  }
@@ -1,7 +1,5 @@
1
1
  package com.externalkeyboard.views.ExternalKeyboardView;
2
2
 
3
- import android.view.View;
4
-
5
3
  import androidx.annotation.NonNull;
6
4
  import androidx.annotation.Nullable;
7
5
 
@@ -32,20 +30,7 @@ public class ExternalKeyboardViewManager extends com.externalkeyboard.ExternalKe
32
30
  @NonNull
33
31
  @Override
34
32
  public ExternalKeyboardView createViewInstance(@NonNull ThemedReactContext context) {
35
- ExternalKeyboardView viewGroup = new ExternalKeyboardView(context);
36
-
37
- viewGroup.setOnHierarchyChangeListener(new ExternalKeyboardView.OnHierarchyChangeListener() {
38
- @Override
39
- public void onChildViewAdded(View parent, View child) {
40
- viewGroup.linkAddView(child);
41
- }
42
-
43
- @Override
44
- public void onChildViewRemoved(View parent, View child) {
45
- viewGroup.linkRemoveView(child);
46
- }
47
- });
48
- return viewGroup;
33
+ return new ExternalKeyboardView(context);
49
34
  }
50
35
 
51
36
  public static Map<String, Object> buildDirectEventMap(String registrationName) {
@@ -138,9 +123,9 @@ public class ExternalKeyboardViewManager extends com.externalkeyboard.ExternalKe
138
123
  }
139
124
 
140
125
  @Override
141
- @ReactProp(name = "haloEffect", defaultBoolean = false)
126
+ @ReactProp(name = "haloEffect", defaultBoolean = true)
142
127
  public void setHaloEffect(ExternalKeyboardView view, boolean value) {
143
- //stub
128
+ view.setFocusHighlight(value);
144
129
  }
145
130
 
146
131
  @Override
@@ -285,4 +270,12 @@ public class ExternalKeyboardViewManager extends com.externalkeyboard.ExternalKe
285
270
  super.receiveCommand(root, commandId, args);
286
271
  }
287
272
  }
273
+
274
+ @Override
275
+ public void onDropViewInstance(@NonNull ReactViewGroup viewGroup) {
276
+ if(viewGroup instanceof ExternalKeyboardView) {
277
+ ((ExternalKeyboardView)viewGroup).onDropViewInstance();
278
+ }
279
+ super.onDropViewInstance(viewGroup);
280
+ }
288
281
  }