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
@@ -0,0 +1,195 @@
1
+ //
2
+ // RNCEKVFocusLinkDelegate.mm
3
+ // react-native-external-keyboard
4
+ //
5
+
6
+ #import <Foundation/Foundation.h>
7
+ #import "RNCEKVFocusLinkDelegate.h"
8
+ #import "RNCEKVFocusGuideHelper.h"
9
+ #import "RNCEKVFocusLinkObserver.h"
10
+ #import "RNCEKVOrderSubscriber.h"
11
+ #import "RNCEKVOrderLinking.h"
12
+ #import "RNCEKVKeyboardFocusableProtocol.h"
13
+
14
+ static NSNumber *const FOCUS_DEFAULT = nil;
15
+ static NSNumber *const FOCUS_LOCK = @0;
16
+ static NSNumber *const FOCUS_HANDLED = @0;
17
+
18
+ @implementation RNCEKVFocusLinkDelegate {
19
+ BOOL _isFocused;
20
+ UIView<RNCEKVFocusOrderProtocol> *_delegate;
21
+ NSMutableDictionary<NSNumber *, UIFocusGuide *> *_sides;
22
+ NSMutableDictionary<NSNumber *, RNCEKVOrderSubscriber *> *_subscribers;
23
+ }
24
+
25
+ - (instancetype)initWithView:(UIView<RNCEKVFocusOrderProtocol> *)delegate {
26
+ self = [super init];
27
+ if (self) {
28
+ _delegate = delegate;
29
+ _isFocused = NO;
30
+ _sides = [NSMutableDictionary dictionary];
31
+ _subscribers = [NSMutableDictionary dictionary];
32
+ }
33
+ return self;
34
+ }
35
+
36
+ - (void)link {
37
+ if (_delegate.orderId != nil) {
38
+ [[RNCEKVOrderLinking sharedInstance] storeOrderId:_delegate.orderId withView:_delegate];
39
+ [self linkId];
40
+ }
41
+ }
42
+
43
+ - (void)unlink {
44
+ if (_delegate.orderId != nil) {
45
+ [[RNCEKVOrderLinking sharedInstance] cleanOrderId:_delegate.orderId];
46
+ [self clear];
47
+ }
48
+ }
49
+
50
+ #pragma mark - Focus helpers
51
+
52
+ - (void)keyboardedViewFocus:(UIView *)view {
53
+ if ([view conformsToProtocol:@protocol(RNCEKVKeyboardFocusableProtocol)]) {
54
+ [(UIView<RNCEKVKeyboardFocusableProtocol> *)view focus];
55
+ }
56
+ }
57
+
58
+ #pragma mark - Guide management
59
+
60
+ - (void)setGuideFor:(RNCEKVFocusGuideDirection)direction withView:(UIView *)view {
61
+ if (!view) return;
62
+ [self removeGuideFor:direction];
63
+ _sides[@(direction)] = [RNCEKVFocusGuideHelper setGuideForDirection:direction
64
+ inView:_delegate
65
+ focusView:view
66
+ enabled:_isFocused];
67
+ }
68
+
69
+ - (void)removeGuideFor:(RNCEKVFocusGuideDirection)direction {
70
+ if (_sides[@(direction)]) {
71
+ [_delegate removeLayoutGuide:_sides[@(direction)]];
72
+ _sides[@(direction)] = nil;
73
+ }
74
+ }
75
+
76
+ - (void)setIsFocused:(BOOL)value {
77
+ _isFocused = value;
78
+ for (NSNumber *key in _sides) {
79
+ _sides[key].enabled = value;
80
+ }
81
+ }
82
+
83
+ #pragma mark - Subscriptions
84
+
85
+ - (void)subscribeToDirection:(RNCEKVFocusGuideDirection)direction linkId:(NSString *)linkId {
86
+ if (!linkId) return;
87
+
88
+ if (_subscribers[@(direction)]) {
89
+ [self clearDirection:direction];
90
+ }
91
+
92
+ RNCEKVFocusGuideDirection capturedDirection = direction;
93
+
94
+ LinkUpdatedCallback onLinkUpdated = ^(UIView *link) {
95
+ [self setGuideFor:capturedDirection withView:link];
96
+ };
97
+
98
+ LinkRemovedCallback onLinkRemoved = ^{
99
+ [self removeGuideFor:capturedDirection];
100
+ };
101
+
102
+ RNCEKVOrderSubscriber *subscriber = [[RNCEKVFocusLinkObserver sharedManager] subscribe:linkId
103
+ onLinkUpdated:onLinkUpdated
104
+ onLinkRemoved:onLinkRemoved];
105
+ _subscribers[@(direction)] = subscriber;
106
+ }
107
+
108
+ - (void)clearDirection:(RNCEKVFocusGuideDirection)direction {
109
+ if (!_subscribers[@(direction)]) return;
110
+ [[RNCEKVFocusLinkObserver sharedManager] unsubscribe:_subscribers[@(direction)]];
111
+ _subscribers[@(direction)] = nil;
112
+ [self removeGuideFor:direction];
113
+ }
114
+
115
+ - (void)refreshDirection:(RNCEKVFocusGuideDirection)direction nextId:(NSString *)nextId {
116
+ [self clearDirection:direction];
117
+ [self subscribeToDirection:direction linkId:nextId];
118
+ }
119
+
120
+ #pragma mark - Public API
121
+
122
+ - (void)linkId {
123
+ RNCEKVFocusLinkObserver *focusLinkObserver = [RNCEKVFocusLinkObserver sharedManager];
124
+ NSString *orderId = _delegate.orderId;
125
+ UIView *view = [_delegate getFocusTargetView];
126
+
127
+ if (orderId != nil) {
128
+ [focusLinkObserver emitWithId:orderId link:view];
129
+ }
130
+
131
+ [self subscribeToDirection:RNCEKVFocusGuideDirectionLeft linkId:_delegate.orderLeft];
132
+ [self subscribeToDirection:RNCEKVFocusGuideDirectionRight linkId:_delegate.orderRight];
133
+ [self subscribeToDirection:RNCEKVFocusGuideDirectionUp linkId:_delegate.orderUp];
134
+ [self subscribeToDirection:RNCEKVFocusGuideDirectionDown linkId:_delegate.orderDown];
135
+ }
136
+
137
+ - (void)refreshId:(NSString *)prev next:(NSString *)next {
138
+ RNCEKVFocusLinkObserver *focusLinkObserver = [RNCEKVFocusLinkObserver sharedManager];
139
+ UIView *view = [_delegate getFocusTargetView];
140
+
141
+ if (prev != nil) {
142
+ [focusLinkObserver emitRemoveWithId:prev];
143
+ [[RNCEKVOrderLinking sharedInstance] cleanOrderId:prev];
144
+ }
145
+
146
+ if (next != nil && view != nil) {
147
+ [[RNCEKVOrderLinking sharedInstance] storeOrderId:next withView:_delegate];
148
+ [focusLinkObserver emitWithId:next link:view];
149
+ }
150
+ }
151
+
152
+ - (void)refreshLeft:(NSString *)next { [self refreshDirection:RNCEKVFocusGuideDirectionLeft nextId:next]; }
153
+ - (void)refreshRight:(NSString *)next { [self refreshDirection:RNCEKVFocusGuideDirectionRight nextId:next]; }
154
+ - (void)refreshUp:(NSString *)next { [self refreshDirection:RNCEKVFocusGuideDirectionUp nextId:next]; }
155
+ - (void)refreshDown:(NSString *)next { [self refreshDirection:RNCEKVFocusGuideDirectionDown nextId:next]; }
156
+
157
+ - (void)clear {
158
+ [self clearDirection:RNCEKVFocusGuideDirectionLeft];
159
+ [self clearDirection:RNCEKVFocusGuideDirectionRight];
160
+ [self clearDirection:RNCEKVFocusGuideDirectionUp];
161
+ [self clearDirection:RNCEKVFocusGuideDirectionDown];
162
+ [self refreshId:_delegate.orderId next:nil];
163
+ }
164
+
165
+ - (NSNumber *)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context {
166
+ UIFocusHeading movementHint = context.focusHeading;
167
+ UIView *current = (UIView *)context.previouslyFocusedItem;
168
+ UIView *targetView = [_delegate getFocusTargetView];
169
+
170
+ BOOL isCurrentDelegate = current != nil
171
+ && [current isKindOfClass:[UIView class]]
172
+ && (current == targetView || [current isDescendantOfView:_delegate]);
173
+ if (isCurrentDelegate) {
174
+ NSUInteger rawFocusLockValue = [_delegate.lockFocus unsignedIntegerValue];
175
+ if ((rawFocusLockValue & movementHint) != 0) {
176
+ return FOCUS_LOCK;
177
+ }
178
+
179
+ NSString *orderId = nil;
180
+ if (movementHint == UIFocusHeadingLast) orderId = _delegate.orderLast;
181
+ else if (movementHint == UIFocusHeadingFirst) orderId = _delegate.orderFirst;
182
+ else if (movementHint == UIFocusHeadingNext) orderId = _delegate.orderForward;
183
+ else if (movementHint == UIFocusHeadingPrevious) orderId = _delegate.orderBackward;
184
+
185
+ if (orderId) {
186
+ UIView *nextView = [[RNCEKVOrderLinking sharedInstance] getOrderView:orderId];
187
+ [self keyboardedViewFocus:nextView];
188
+ return FOCUS_HANDLED;
189
+ }
190
+ }
191
+
192
+ return FOCUS_DEFAULT;
193
+ }
194
+
195
+ @end
@@ -13,20 +13,18 @@
13
13
  @protocol RNCEKVFocusOrderProtocol <NSObject>
14
14
 
15
15
  @property (nonatomic, strong) NSString* orderGroup;
16
- @property NSNumber* lockFocus;
17
- @property NSNumber* orderPosition;
16
+ @property (nonatomic, strong) NSNumber* lockFocus;
17
+ @property (nonatomic, strong) NSNumber* orderPosition;
18
18
  @property (nonatomic, strong) NSString* orderLeft;
19
19
  @property (nonatomic, strong) NSString* orderRight;
20
20
  @property (nonatomic, strong) NSString* orderUp;
21
21
  @property (nonatomic, strong) NSString* orderDown;
22
- @property NSString* orderForward;
23
- @property NSString* orderBackward;
24
- @property NSString* orderLast;
25
- @property NSString* orderFirst;
26
-
22
+ @property (nonatomic, strong) NSString* orderForward;
23
+ @property (nonatomic, strong) NSString* orderBackward;
24
+ @property (nonatomic, strong) NSString* orderLast;
25
+ @property (nonatomic, strong) NSString* orderFirst;
27
26
  @property (nonatomic, strong) NSString* orderId;
28
27
 
29
- - (UIViewController *)reactViewController;
30
28
  - (UIView *)getFocusTargetView;
31
29
 
32
30
  @end
@@ -0,0 +1,25 @@
1
+ //
2
+ // RNCEKVFocusSequenceDelegate.h
3
+ // react-native-external-keyboard
4
+ //
5
+
6
+ #ifndef RNCEKVFocusSequenceDelegate_h
7
+ #define RNCEKVFocusSequenceDelegate_h
8
+
9
+ #import <Foundation/Foundation.h>
10
+ #import "RNCEKVFocusOrderProtocol.h"
11
+
12
+ @interface RNCEKVFocusSequenceDelegate : NSObject
13
+
14
+ - (instancetype _Nonnull)initWithView:(UIView<RNCEKVFocusOrderProtocol> *_Nonnull)view;
15
+
16
+ - (NSNumber *_Nullable)shouldUpdateFocusInContext:(UIFocusUpdateContext *_Nonnull)context;
17
+
18
+ - (void)link;
19
+ - (void)unlink;
20
+ - (void)updatePosition:(NSNumber *_Nullable)position;
21
+ - (void)updateOrderGroup:(NSString *_Nullable)orderGroup;
22
+
23
+ @end
24
+
25
+ #endif /* RNCEKVFocusSequenceDelegate_h */
@@ -0,0 +1,163 @@
1
+ //
2
+ // RNCEKVFocusSequenceDelegate.mm
3
+ // react-native-external-keyboard
4
+ //
5
+
6
+ #import <Foundation/Foundation.h>
7
+ #import "RNCEKVFocusSequenceDelegate.h"
8
+ #import "RNCEKVOrderLinking.h"
9
+ #import "RNCEKVOrderRelationship.h"
10
+ #import "RNCEKVKeyboardFocusableProtocol.h"
11
+ #import "UIViewController+RNCEKVExternalKeyboard.h"
12
+ #import "UIView+React.h"
13
+
14
+ static NSNumber *const FOCUS_DEFAULT = nil;
15
+ static NSNumber *const FOCUS_HANDLED = @0;
16
+
17
+ @implementation RNCEKVFocusSequenceDelegate {
18
+ BOOL _isLinked;
19
+ UIView<RNCEKVFocusOrderProtocol> *_delegate;
20
+ }
21
+
22
+ - (instancetype)initWithView:(UIView<RNCEKVFocusOrderProtocol> *)delegate {
23
+ self = [super init];
24
+ if (self) {
25
+ _delegate = delegate;
26
+ }
27
+ return self;
28
+ }
29
+
30
+ - (void)link {
31
+ if (_delegate.orderPosition != nil && _delegate.orderGroup != nil && !_isLinked) {
32
+ [[RNCEKVOrderLinking sharedInstance] add:_delegate.orderPosition withOrderKey:_delegate.orderGroup withObject:_delegate];
33
+ _isLinked = YES;
34
+ }
35
+ }
36
+
37
+ - (void)unlink {
38
+ if (_delegate.orderPosition != nil && _delegate.orderGroup != nil && _isLinked) {
39
+ [[RNCEKVOrderLinking sharedInstance] remove:_delegate.orderPosition withOrderKey:_delegate.orderGroup];
40
+ }
41
+ _isLinked = NO;
42
+ }
43
+
44
+ - (void)updatePosition:(NSNumber *)position {
45
+ if (position == nil || _delegate.orderPosition == position || (_delegate.orderPosition != nil && [_delegate.orderPosition isEqualToNumber:position])) {
46
+ return;
47
+ }
48
+ if (_delegate.orderGroup != nil && _delegate.superview != nil && _isLinked) {
49
+ [[RNCEKVOrderLinking sharedInstance] update:position lastPosition:_delegate.orderPosition withOrderKey:_delegate.orderGroup withView:_delegate];
50
+ }
51
+ }
52
+
53
+ - (void)updateOrderGroup:(NSString *)orderGroup {
54
+ if (_delegate.orderPosition != nil && _delegate.superview != nil) {
55
+ [[RNCEKVOrderLinking sharedInstance] updateOrderKey:_delegate.orderGroup next:orderGroup position:_delegate.orderPosition withView:_delegate];
56
+ }
57
+ }
58
+
59
+ #pragma mark - Focus helpers
60
+
61
+ - (void)keyboardedViewFocus:(UIView *)view {
62
+ if ([view conformsToProtocol:@protocol(RNCEKVKeyboardFocusableProtocol)]) {
63
+ [(UIView<RNCEKVKeyboardFocusableProtocol> *)view focus];
64
+ }
65
+ }
66
+
67
+ - (void)defaultViewFocus:(UIView *)view {
68
+ UIViewController *controller = _delegate.reactViewController;
69
+ if (controller != nil) {
70
+ [controller rncekvFocusView:view];
71
+ }
72
+ }
73
+
74
+ #pragma mark - Sequential navigation
75
+
76
+ - (BOOL)handleNextFocus:(UIView *)current
77
+ currentIndex:(NSInteger)currentIndex
78
+ orderRelationship:(RNCEKVOrderRelationship *)orderRelationship {
79
+ UIView *entry = orderRelationship.entry;
80
+ UIView *exit = orderRelationship.exit;
81
+
82
+ if (entry == current) {
83
+ [self keyboardedViewFocus:[orderRelationship getItem:0]];
84
+ return NO;
85
+ }
86
+
87
+ if (currentIndex == orderRelationship.count - 1 && exit) {
88
+ [self defaultViewFocus:exit];
89
+ return YES;
90
+ }
91
+
92
+ if (currentIndex >= 0 && currentIndex < orderRelationship.count - 1) {
93
+ [self keyboardedViewFocus:[orderRelationship getItem:currentIndex + 1]];
94
+ return YES;
95
+ }
96
+
97
+ return NO;
98
+ }
99
+
100
+ - (BOOL)handlePrevFocus:(UIView *)current
101
+ currentIndex:(NSInteger)currentIndex
102
+ orderRelationship:(RNCEKVOrderRelationship *)orderRelationship {
103
+ UIView *exit = orderRelationship.exit;
104
+ UIView *entry = orderRelationship.entry;
105
+ int orderCount = [orderRelationship count];
106
+
107
+ if (exit == current) {
108
+ [self keyboardedViewFocus:[orderRelationship getItem:orderCount - 1]];
109
+ return YES;
110
+ }
111
+
112
+ if (currentIndex == 0 && entry) {
113
+ [self defaultViewFocus:entry];
114
+ return YES;
115
+ }
116
+
117
+ if (currentIndex > 0 && currentIndex <= orderCount - 1) {
118
+ [self keyboardedViewFocus:[orderRelationship getItem:currentIndex - 1]];
119
+ return YES;
120
+ }
121
+
122
+ return NO;
123
+ }
124
+
125
+ #pragma mark - shouldUpdateFocusInContext
126
+
127
+ - (NSNumber *)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context {
128
+ UIFocusHeading movementHint = context.focusHeading;
129
+ UIView *next = (UIView *)context.nextFocusedItem;
130
+ UIView *current = (UIView *)context.previouslyFocusedItem;
131
+
132
+ if (_delegate.orderGroup && _delegate.orderPosition != nil) {
133
+ RNCEKVOrderRelationship *orderRelationship = [[RNCEKVOrderLinking sharedInstance] getInfo:_delegate.orderGroup];
134
+ if ([orderRelationship getArray].count == 0) {
135
+ return FOCUS_DEFAULT;
136
+ }
137
+
138
+ int currentIndex = [orderRelationship getItemIndex:current];
139
+ int nextIndex = [orderRelationship getItemIndex:next];
140
+
141
+ if (orderRelationship.entry == nil && currentIndex == -1 && movementHint == UIFocusHeadingNext) {
142
+ orderRelationship.entry = current;
143
+ }
144
+
145
+ if (orderRelationship.exit == nil && nextIndex == -1 && movementHint == UIFocusHeadingNext) {
146
+ orderRelationship.exit = next;
147
+ }
148
+
149
+ if (movementHint == UIFocusHeadingNext) {
150
+ BOOL handled = [self handleNextFocus:current currentIndex:currentIndex orderRelationship:orderRelationship];
151
+ return handled ? FOCUS_HANDLED : FOCUS_DEFAULT;
152
+ }
153
+
154
+ if (movementHint == UIFocusHeadingPrevious) {
155
+ BOOL handled = [self handlePrevFocus:current currentIndex:currentIndex orderRelationship:orderRelationship];
156
+ return handled ? FOCUS_HANDLED : FOCUS_DEFAULT;
157
+ }
158
+ }
159
+
160
+ return FOCUS_DEFAULT;
161
+ }
162
+
163
+ @end
@@ -13,13 +13,9 @@
13
13
 
14
14
  @interface RNCEKVGroupIdentifierDelegate : NSObject
15
15
 
16
- - (instancetype _Nonnull )initWithView:(UIView<RNCEKVGroupIdentifierProtocol> *_Nonnull)view;
16
+ - (instancetype _Nonnull)initWithView:(UIView<RNCEKVGroupIdentifierProtocol> *_Nonnull)view;
17
17
 
18
- - (NSString*_Nonnull) getFocusGroupIdentifier;
19
- - (void)updateGroupIdentifier;
20
- - (void)clear;
21
- - (void)clearSubview:(UIView*_Nullable)subview;
22
- - (void)syncCustomGroupId;
18
+ @property (nonatomic, readonly, nonnull) NSString *focusGroupIdentifier;
23
19
 
24
20
  @end
25
21
 
@@ -8,7 +8,6 @@
8
8
  #import <Foundation/Foundation.h>
9
9
 
10
10
  #import "RNCEKVGroupIdentifierDelegate.h"
11
- #import "RNCEKVFocusEffectUtility.h"
12
11
 
13
12
  #ifdef RCT_NEW_ARCH_ENABLED
14
13
  #import "RCTViewComponentView+RNCEKVExternalKeyboard.h"
@@ -29,89 +28,18 @@
29
28
  }
30
29
 
31
30
 
32
- - (NSString*) getTagId {
33
- if(_tagId) {
34
- return _tagId;
31
+ - (NSString *)tagId {
32
+ if (!_tagId) {
33
+ _tagId = [NSString stringWithFormat:@"app.group.%@", [NSUUID UUID].UUIDString];
35
34
  }
36
-
37
- NSUUID *uuid = [NSUUID UUID];
38
- NSString *uniqueID = [uuid UUIDString];
39
- _tagId = [NSString stringWithFormat:@"app.group.%@", uniqueID];
40
-
41
35
  return _tagId;
42
36
  }
43
37
 
44
-
45
- - (NSString*) getFocusGroupIdentifier {
46
- if (@available(iOS 14.0, *)) {
47
- if(_delegate.customGroupId) {
48
- return _delegate.customGroupId;
49
- }
50
-
51
- return [self getTagId];
52
- } else {
53
- return nil;
54
- }
55
- }
56
-
57
-
58
- #ifdef RCT_NEW_ARCH_ENABLED
59
- - (void) updateGroupIdentifier {
60
- if (@available(iOS 14.0, *)) {
61
- UIView* focus = [_delegate getFocusTargetView];
62
-
63
- NSString* identifier = [self getFocusGroupIdentifier];
64
- if([focus isKindOfClass:[RCTViewComponentView class]]) {
65
- ((RCTViewComponentView*)focus).rncekvCustomGroup = identifier;
66
- } else {
67
- focus.focusGroupIdentifier = identifier;
68
- }
69
- }
70
- }
71
-
72
- #else
73
-
74
- - (void) updateGroupIdentifier {
75
- if (@available(iOS 14.0, *)) {
76
- UIView* focus = [_delegate getFocusTargetView];
77
- focus.focusGroupIdentifier = [self getFocusGroupIdentifier];
78
- }
79
- }
80
-
81
- #endif
82
-
83
- - (void) clear {
84
- if (@available(iOS 14.0, *)) {
85
- UIView* focus = [_delegate getFocusTargetView];
86
- [self clearSubview: focus];
87
- }
88
- }
89
-
90
- #ifdef RCT_NEW_ARCH_ENABLED
91
- - (void)clearSubview: (UIView*_Nullable)subview {
92
- if(!subview) return;
93
-
94
- if (@available(iOS 14.0, *)) {
95
-
96
- if(subview) {
97
- if([subview isKindOfClass:[RCTViewComponentView class]]) {
98
- ((RCTViewComponentView*)subview).rncekvCustomGroup = nil;
99
- } else {
100
- subview.focusGroupIdentifier = nil;
101
- }
102
- }
103
- }
104
- }
105
- #else
106
-
107
- - (void)clearSubview: (UIView*_Nullable)subview {
108
- if(!subview) return;
109
-
38
+ - (NSString *)focusGroupIdentifier {
110
39
  if (@available(iOS 14.0, *)) {
111
- subview.focusGroupIdentifier = nil;
40
+ return _delegate.customGroupId ?: self.tagId;
112
41
  }
42
+ return self.tagId;
113
43
  }
114
44
 
115
- #endif
116
-
117
45
  @end
@@ -13,11 +13,10 @@
13
13
 
14
14
  @interface RNCEKVHaloDelegate : NSObject
15
15
 
16
- - (instancetype _Nonnull )initWithView:(UIView<RNCEKVHaloProtocol> *_Nonnull)view;
16
+ - (instancetype _Nonnull)initWithView:(UIView<RNCEKVHaloProtocol> *_Nonnull)view;
17
17
 
18
- - (void)displayHalo:(BOOL)force;
19
- - (void)displayHalo;
20
- - (void)updateHalo;
18
+ @property (nonatomic, readonly, nullable) UIFocusEffect *focusEffect;
19
+ - (void)invalidate;
21
20
  - (void)clear;
22
21
 
23
22
  @end