react-native-external-keyboard 0.5.6 → 0.6.1-rc

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 (102) hide show
  1. package/README.md +277 -14
  2. package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegate.java +213 -0
  3. package/android/src/main/java/com/externalkeyboard/helper/FocusHelper.java +44 -0
  4. package/android/src/main/java/com/externalkeyboard/helper/Linking/A11yOrderLinking.java +81 -0
  5. package/android/src/main/java/com/externalkeyboard/helper/Linking/LinkingQueue.java +94 -0
  6. package/android/src/main/java/com/externalkeyboard/helper/ReactNativeVersionChecker.java +24 -0
  7. package/android/src/main/java/com/externalkeyboard/services/FocusLinkObserver/FocusLinkObserver.java +131 -0
  8. package/android/src/main/java/com/externalkeyboard/services/FocusLinkObserver/FocusLinkObserverSingleton.java +20 -0
  9. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardView.java +144 -0
  10. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardViewManager.java +128 -8
  11. package/android/src/main/java/com/externalkeyboard/views/KeyboardFocusGroup/KeyboardFocusGroupManager.java +7 -3
  12. package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapper.java +2 -13
  13. package/android/src/oldarch/ExternalKeyboardViewManagerSpec.java +25 -0
  14. package/android/src/oldarch/KeyboardFocusGroupManagerSpec.java +8 -1
  15. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.h +33 -0
  16. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.mm +577 -0
  17. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderProtocol.h +34 -0
  18. package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.h +1 -0
  19. package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.mm +9 -0
  20. package/ios/Helpers/RNCEKVPropHelper/RNCEKVPropHelper.h +22 -0
  21. package/ios/Helpers/RNCEKVPropHelper/RNCEKVPropHelper.mm +48 -0
  22. package/ios/Services/RNCEKVFocusLinkObserver.h +27 -0
  23. package/ios/Services/RNCEKVFocusLinkObserver.mm +101 -0
  24. package/ios/Services/RNCEKVFocusLinkObserverManager.h +23 -0
  25. package/ios/Services/RNCEKVFocusLinkObserverManager.mm +30 -0
  26. package/ios/Services/RNCEKVOrderLinking.h +33 -0
  27. package/ios/Services/RNCEKVOrderLinking.mm +143 -0
  28. package/ios/Services/RNCEKVOrderSubscriber.h +24 -0
  29. package/ios/Services/RNCEKVOrderSubscriber.mm +23 -0
  30. package/ios/Services/RNCEKVRelashioship.h +28 -0
  31. package/ios/Services/RNCEKVRelashioship.mm +61 -0
  32. package/ios/Services/RNCEKVSortedMap.h +22 -0
  33. package/ios/Services/RNCEKVSortedMap.mm +112 -0
  34. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.h +34 -3
  35. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.mm +214 -54
  36. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.h +9 -0
  37. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.mm +80 -55
  38. package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.h +2 -0
  39. package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.mm +161 -3
  40. package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroupManager.mm +6 -0
  41. package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js +56 -3
  42. package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
  43. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js +30 -0
  44. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js.map +1 -0
  45. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.js.map +1 -1
  46. package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.js.map +1 -1
  47. package/lib/commonjs/context/OrderFocusContext.js +23 -0
  48. package/lib/commonjs/context/OrderFocusContext.js.map +1 -0
  49. package/lib/commonjs/index.js +19 -0
  50. package/lib/commonjs/index.js.map +1 -1
  51. package/lib/commonjs/nativeSpec/ExternalKeyboardViewNativeComponent.js.map +1 -1
  52. package/lib/commonjs/nativeSpec/KeyboardFocusGroupNativeComponent.js.map +1 -1
  53. package/lib/commonjs/types/BaseKeyboardView.js +12 -0
  54. package/lib/commonjs/types/BaseKeyboardView.js.map +1 -1
  55. package/lib/commonjs/utils/withKeyboardFocus.js +25 -1
  56. package/lib/commonjs/utils/withKeyboardFocus.js.map +1 -1
  57. package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js +55 -2
  58. package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
  59. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js +23 -0
  60. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js.map +1 -0
  61. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.js.map +1 -1
  62. package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.js.map +1 -1
  63. package/lib/module/context/OrderFocusContext.js +14 -0
  64. package/lib/module/context/OrderFocusContext.js.map +1 -0
  65. package/lib/module/index.js +1 -0
  66. package/lib/module/index.js.map +1 -1
  67. package/lib/module/nativeSpec/ExternalKeyboardViewNativeComponent.js.map +1 -1
  68. package/lib/module/nativeSpec/KeyboardFocusGroupNativeComponent.js.map +1 -1
  69. package/lib/module/types/BaseKeyboardView.js +11 -1
  70. package/lib/module/types/BaseKeyboardView.js.map +1 -1
  71. package/lib/module/utils/withKeyboardFocus.js +25 -1
  72. package/lib/module/utils/withKeyboardFocus.js.map +1 -1
  73. package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts +1 -1
  74. package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts.map +1 -1
  75. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.d.ts +24 -0
  76. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.d.ts.map +1 -0
  77. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.d.ts +1 -0
  78. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.d.ts.map +1 -1
  79. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.d.ts +2 -0
  80. package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.d.ts.map +1 -1
  81. package/lib/typescript/src/context/OrderFocusContext.d.ts +10 -0
  82. package/lib/typescript/src/context/OrderFocusContext.d.ts.map +1 -0
  83. package/lib/typescript/src/index.d.ts +1 -0
  84. package/lib/typescript/src/index.d.ts.map +1 -1
  85. package/lib/typescript/src/nativeSpec/ExternalKeyboardViewNativeComponent.d.ts +12 -0
  86. package/lib/typescript/src/nativeSpec/ExternalKeyboardViewNativeComponent.d.ts.map +1 -1
  87. package/lib/typescript/src/nativeSpec/KeyboardFocusGroupNativeComponent.d.ts +1 -0
  88. package/lib/typescript/src/nativeSpec/KeyboardFocusGroupNativeComponent.d.ts.map +1 -1
  89. package/lib/typescript/src/types/BaseKeyboardView.d.ts +24 -0
  90. package/lib/typescript/src/types/BaseKeyboardView.d.ts.map +1 -1
  91. package/lib/typescript/src/utils/withKeyboardFocus.d.ts.map +1 -1
  92. package/package.json +1 -1
  93. package/src/components/BaseKeyboardView/BaseKeyboardView.tsx +77 -4
  94. package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.tsx +39 -0
  95. package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.tsx +1 -0
  96. package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.tsx +1 -0
  97. package/src/context/OrderFocusContext.tsx +25 -0
  98. package/src/index.tsx +5 -0
  99. package/src/nativeSpec/ExternalKeyboardViewNativeComponent.ts +12 -0
  100. package/src/nativeSpec/KeyboardFocusGroupNativeComponent.ts +1 -0
  101. package/src/types/BaseKeyboardView.ts +26 -0
  102. package/src/utils/withKeyboardFocus.tsx +24 -0
@@ -0,0 +1,112 @@
1
+ //
2
+ // RNCEKVSortedMap.m
3
+ // A11yOrder
4
+ //
5
+ // Created by Artur Kalach on 13/07/2024.
6
+ // Copyright © 2024 Facebook. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+ #import "RNCEKVSortedMap.h"
11
+
12
+ @implementation RNCEKVSortedMap {
13
+ NSMutableDictionary *_dirctionary;
14
+ NSMutableArray *_sortedKeys;
15
+ NSMutableArray *_cachedResult;
16
+ BOOL _hasBeenChanged;
17
+ }
18
+
19
+ - (instancetype)init {
20
+ self = [super init];
21
+ if (self) {
22
+ _dirctionary = [NSMutableDictionary dictionary];
23
+ _sortedKeys = [NSMutableArray array];
24
+ _cachedResult = [NSMutableArray array];
25
+ _hasBeenChanged = YES;
26
+ }
27
+ return self;
28
+ }
29
+
30
+ - (void)updateSortedKey:(NSNumber*)position {
31
+ if([_sortedKeys count] == 0) {
32
+ [_sortedKeys addObject: position];
33
+ } else {
34
+ NSInteger indexOfFirstLarger = -1;
35
+
36
+ for (NSInteger i = 0; i < _sortedKeys.count; i++) {
37
+ NSNumber *number = _sortedKeys[i];
38
+ if ([number integerValue] > [position integerValue]) {
39
+ indexOfFirstLarger = i;
40
+ break;
41
+ }
42
+ }
43
+
44
+
45
+ if(indexOfFirstLarger == -1) {
46
+ [_sortedKeys addObject: position];
47
+ } else {
48
+ [_sortedKeys insertObject:position atIndex:indexOfFirstLarger];
49
+ }
50
+ }
51
+ }
52
+
53
+ - (void)put:(NSNumber*)position withObject:(NSObject*)obj {
54
+ _hasBeenChanged = YES;
55
+ if([_dirctionary objectForKey:position] == nil) {
56
+ [self updateSortedKey: position];
57
+ }
58
+ [_dirctionary setObject: obj forKey:position];
59
+ }
60
+
61
+ - (void)remove:(NSNumber*)position {
62
+ _hasBeenChanged = YES;
63
+ NSUInteger positionIndex = [_sortedKeys indexOfObject:position];
64
+ if (positionIndex != NSNotFound) {
65
+ [_sortedKeys removeObjectAtIndex:positionIndex];
66
+ }
67
+ [_dirctionary removeObjectForKey:position];
68
+ }
69
+
70
+
71
+ - (void)remove:(NSNumber*)position withObject:(NSObject*)obj {
72
+ if([_dirctionary objectForKey:position] == obj) {
73
+ NSUInteger positionIndex = [_sortedKeys indexOfObject:position];
74
+ if (positionIndex != NSNotFound) {
75
+ [_sortedKeys removeObjectAtIndex:positionIndex];
76
+ }
77
+ [_dirctionary removeObjectForKey:position];
78
+ }
79
+ }
80
+
81
+ - (void)clear {
82
+ [_dirctionary removeAllObjects];
83
+ [_sortedKeys removeAllObjects];
84
+ [_cachedResult removeAllObjects];
85
+ }
86
+
87
+ - (void)update:(NSNumber*)lastPosition withPosition:(NSNumber*)position withObject:(NSObject*)obj {
88
+ _hasBeenChanged = YES;
89
+ [self remove:lastPosition withObject: obj];
90
+ [self put:position withObject:obj];
91
+ }
92
+
93
+ - (NSArray*)getValues {
94
+ if(_hasBeenChanged) {
95
+ [_cachedResult removeAllObjects];
96
+ for (NSNumber *itemPosition in _sortedKeys) {
97
+ NSObject *item = [_dirctionary objectForKey:itemPosition];
98
+ if(item != nil) {
99
+ [_cachedResult addObject:item];
100
+ }
101
+ }
102
+ return _cachedResult;
103
+ } else {
104
+ return _cachedResult;
105
+ }
106
+ }
107
+
108
+ -(BOOL)isEmpty {
109
+ return [_dirctionary count] == 0;
110
+ }
111
+
112
+ @end
@@ -3,16 +3,21 @@
3
3
  #import "RNCEKVKeyboardKeyPressHandler.h"
4
4
  #import <UIKit/UIKit.h>
5
5
  #import "RNCEKVFocusProtocol.h"
6
+ #import "RNCEKVFocusOrderProtocol.h"
6
7
  #import "RNCEKVHaloProtocol.h"
7
8
  #import "RNCEKVGroupIdentifierProtocol.h"
8
9
 
9
10
  #ifdef RCT_NEW_ARCH_ENABLED
10
11
  #import <React/RCTViewComponentView.h>
11
12
 
12
-
13
13
  NS_ASSUME_NONNULL_BEGIN
14
14
 
15
- @interface RNCEKVExternalKeyboardView : RCTViewComponentView <UIContextMenuInteractionDelegate, RNCEKVHaloProtocol, RNCEKVFocusProtocol, RNCEKVGroupIdentifierProtocol>
15
+ #define RKNA_PROP_UPDATE(prop, setter, newProps) \
16
+ if ([RNCEKVPropHelper isPropChanged: _##prop stringValue: newProps.prop]) { \
17
+ [self setter: [RNCEKVPropHelper unwrapStringValue: newProps.prop]]; \
18
+ }
19
+
20
+ @interface RNCEKVExternalKeyboardView : RCTViewComponentView <UIContextMenuInteractionDelegate, RNCEKVHaloProtocol, RNCEKVFocusProtocol, RNCEKVFocusOrderProtocol, RNCEKVGroupIdentifierProtocol>
16
21
  @property (nonatomic, strong, nullable) NSNumber *isHaloActive;
17
22
  @property BOOL canBeFocused;
18
23
  @property BOOL hasOnPressUp;
@@ -26,6 +31,19 @@ NS_ASSUME_NONNULL_BEGIN
26
31
  @property (nullable, nonatomic, strong) UIView* myPreferredFocusedView;
27
32
  @property (nonatomic, strong, nullable) NSString *customGroupId;
28
33
  @property BOOL autoFocus;
34
+ @property NSNumber* orderPosition;
35
+ @property NSNumber* lockFocus;
36
+ @property (nonatomic, strong) NSString* orderGroup;
37
+ @property (nonatomic, strong) NSString* orderId;
38
+ @property (nonatomic, strong) NSString* orderLeft;
39
+ @property (nonatomic, strong) NSString* orderRight;
40
+ @property (nonatomic, strong) NSString* orderUp;
41
+ @property (nonatomic, strong) NSString* orderDown;
42
+ @property NSString* orderForward;
43
+ @property NSString* orderBackward;
44
+ @property NSString* orderLast;
45
+ @property NSString* orderFirst;
46
+ @property BOOL isLinked;
29
47
 
30
48
  - (UIView*)getFocusTargetView;
31
49
 
@@ -40,7 +58,7 @@ NS_ASSUME_NONNULL_END
40
58
 
41
59
 
42
60
  #import <React/RCTView.h>
43
- @interface RNCEKVExternalKeyboardView : RCTView <UIContextMenuInteractionDelegate, RNCEKVHaloProtocol, RNCEKVFocusProtocol, RNCEKVGroupIdentifierProtocol>
61
+ @interface RNCEKVExternalKeyboardView : RCTView <UIContextMenuInteractionDelegate, RNCEKVHaloProtocol, RNCEKVFocusOrderProtocol, RNCEKVFocusProtocol, RNCEKVGroupIdentifierProtocol>
44
62
 
45
63
  @property BOOL autoFocus;
46
64
  @property BOOL canBeFocused;
@@ -59,6 +77,19 @@ NS_ASSUME_NONNULL_END
59
77
  @property (nonatomic, copy) RCTDirectEventBlock onKeyDownPress;
60
78
  @property (nonatomic, copy) RCTBubblingEventBlock onBubbledContextMenuPress;
61
79
  @property (nonatomic, strong, nullable) NSString *customGroupId;
80
+ @property NSNumber* orderPosition;
81
+ @property NSNumber* lockFocus;
82
+ @property (nonatomic, strong)NSString* orderGroup;
83
+ @property (nonatomic, strong) NSString* orderId;
84
+ @property (nonatomic, strong)NSString* orderLeft;
85
+ @property (nonatomic, strong)NSString* orderRight;
86
+ @property (nonatomic, strong) NSString* orderUp;
87
+ @property (nonatomic, strong) NSString* orderDown;
88
+ @property NSString* orderForward;
89
+ @property NSString* orderBackward;
90
+ @property NSString* orderLast;
91
+ @property NSString* orderFirst;
92
+ @property BOOL isLinked;
62
93
 
63
94
  - (UIView*)getFocusTargetView;
64
95
 
@@ -6,6 +6,8 @@
6
6
  #import "UIViewController+RNCEKVExternalKeyboard.h"
7
7
  #import <React/RCTViewManager.h>
8
8
  #import <UIKit/UIKit.h>
9
+ #import "RNCEKVFocusOrderDelegate.h"
10
+ #import "RNCEKVOrderLinking.h"
9
11
 
10
12
  #ifdef RCT_NEW_ARCH_ENABLED
11
13
  #import <react/renderer/components/RNExternalKeyboardViewSpec/ComponentDescriptors.h>
@@ -14,9 +16,12 @@
14
16
  #import <react/renderer/components/RNExternalKeyboardViewSpec/RCTComponentViewHelpers.h>
15
17
  #include <string>
16
18
 
19
+ #import "RNCEKVPropHelper.h"
17
20
  #import "RCTFabricComponentsPlugins.h"
18
21
  #import "RNCEKVFabricEventHelper.h"
19
22
  #import <React/RCTConversions.h>
23
+ #import <stdlib.h>
24
+
20
25
 
21
26
  using namespace facebook::react;
22
27
 
@@ -31,21 +36,90 @@ using namespace facebook::react;
31
36
  RNCEKVHaloDelegate *_haloDelegate;
32
37
  RNCEKVFocusDelegate *_focusDelegate;
33
38
  RNCEKVGroupIdentifierDelegate *_gIdDelegate;
34
-
39
+ RNCEKVFocusOrderDelegate *_focusOrderDelegate;
40
+
35
41
  NSNumber *_isFocused;
36
42
  BOOL _isAttachedToWindow;
37
43
  BOOL _isAttachedToController;
44
+ BOOL _isLinked;
45
+ BOOL _isIdLinked;
46
+ }
47
+
48
+ - (void)link:(UIView *)subview {
49
+ if(_orderPosition != nil && _orderGroup != nil && !_isLinked) {
50
+ [[RNCEKVOrderLinking sharedInstance] add: _orderPosition withOrderKey: _orderGroup withObject:self];
51
+ _isLinked = YES;
52
+ }
53
+ if(_orderId != nil) {
54
+ [[RNCEKVOrderLinking sharedInstance] storeOrderId:_orderId withView: self];
55
+ [_focusOrderDelegate linkId];
56
+ _isIdLinked = YES;
57
+ }
38
58
  }
39
59
 
60
+ - (void)unlink{
61
+ if(_orderPosition != nil && _orderGroup != nil && _isLinked) {
62
+ [[RNCEKVOrderLinking sharedInstance] remove:_orderPosition withOrderKey: _orderGroup];
63
+ }
64
+
65
+ if(_orderId != nil) {
66
+ [[RNCEKVOrderLinking sharedInstance] cleanOrderId:_orderId];
67
+ [_focusOrderDelegate clear];
68
+ }
69
+
70
+ if (_customGroupId && _gIdDelegate) {
71
+ [_gIdDelegate clear];
72
+ }
73
+
74
+ _isLinked = NO;
75
+ _isIdLinked = NO;
76
+ }
77
+
78
+
79
+ - (void)onAttached
80
+ {
81
+ if(self.subviews.count > 0) {
82
+ [self link: self.subviews[0]];
83
+ }
84
+ }
85
+
86
+ - (void)onDetached
87
+ {
88
+ [self unlink];
89
+ }
90
+
91
+
40
92
  @synthesize haloCornerRadius = _haloCornerRadius;
41
93
  @synthesize haloExpendX = _haloExpendX;
42
94
  @synthesize haloExpendY = _haloExpendY;
43
95
 
96
+ - (void)setOrderLeft:(NSString *)orderLeft {
97
+ [_focusOrderDelegate refreshLeft: _orderLeft next: orderLeft];
98
+ _orderLeft = orderLeft;
99
+ }
100
+
101
+ - (void)setOrderRight:(NSString *)orderRight {
102
+ [_focusOrderDelegate refreshRight: _orderRight next: orderRight];
103
+ _orderRight = orderRight;
104
+ }
105
+
106
+
107
+ - (void)setOrderUp:(NSString *)orderUp {
108
+ [_focusOrderDelegate refreshUp: _orderUp next: orderUp];
109
+ _orderUp = orderUp;
110
+ }
111
+
112
+ - (void)setOrderDown:(NSString *)orderDown {
113
+ [_focusOrderDelegate refreshDown: _orderDown next: orderDown];
114
+ _orderDown = orderDown;
115
+ }
116
+
117
+
44
118
  - (instancetype)initWithFrame:(CGRect)frame {
45
119
  if (self = [super initWithFrame:frame]) {
46
120
  #ifdef RCT_NEW_ARCH_ENABLED
47
121
  static const auto defaultProps =
48
- std::make_shared<const ExternalKeyboardViewProps>();
122
+ std::make_shared<const ExternalKeyboardViewProps>();
49
123
  _props = defaultProps;
50
124
  #endif
51
125
  _isAttachedToController = NO;
@@ -55,35 +129,88 @@ using namespace facebook::react;
55
129
  _haloDelegate = [[RNCEKVHaloDelegate alloc] initWithView:self];
56
130
  _focusDelegate = [[RNCEKVFocusDelegate alloc] initWithView:self];
57
131
  _gIdDelegate = [[RNCEKVGroupIdentifierDelegate alloc] initWithView:self];
58
-
132
+ _focusOrderDelegate = [[RNCEKVFocusOrderDelegate alloc] initWithView: self];
133
+
59
134
  if (@available(iOS 13.0, *)) {
60
135
  UIContextMenuInteraction *interaction =
61
- [[UIContextMenuInteraction alloc] initWithDelegate:self];
136
+ [[UIContextMenuInteraction alloc] initWithDelegate:self];
62
137
  [self addInteraction:interaction];
63
138
  }
64
139
  }
65
-
140
+
66
141
  return self;
67
142
  }
68
143
 
69
144
  - (void)cleanReferences {
145
+ [_focusOrderDelegate clear];
146
+ [_haloDelegate clear];
147
+ [_gIdDelegate clear];
70
148
  _isAttachedToController = NO;
71
149
  _isAttachedToWindow = NO;
72
150
  _isHaloActive = @2; // ToDo RNCEKV-0
73
151
  _haloExpendX = 0;
74
152
  _haloExpendY = 0;
75
153
  _haloCornerRadius = 0;
154
+ _orderGroup = nil;
155
+ _orderPosition = nil;
156
+ _orderLeft = nil;
157
+ _orderRight = nil;
158
+ _orderUp = nil;
159
+ _orderDown = nil;
160
+ _orderId = nil;
161
+ _lockFocus = nil;
76
162
  _customGroupId = nil;
77
163
  _enableA11yFocus = NO;
78
- [_haloDelegate clear];
79
- [_gIdDelegate clear];
164
+ _isLinked = NO;
80
165
  self.focusGroupIdentifier = nil;
81
166
  }
82
167
 
168
+ - (void)setOrderGroup:(NSString *)orderGroup{
169
+ [self updateOrderGroup:_orderGroup next: orderGroup];
170
+ _orderGroup = orderGroup;
171
+ }
172
+
173
+ - (void)updateOrderGroup:(NSString *)prev next:(NSString*)next {
174
+ if(prev != nil && _orderPosition != nil && self.subviews.count > 0) {
175
+ [[RNCEKVOrderLinking sharedInstance] updateOrderKey:(NSString *)prev next:next position:_orderPosition withView: self];
176
+ }
177
+ }
178
+
179
+ - (void)setOrderId:(NSString*) next {
180
+ [_focusOrderDelegate refreshId:_orderId next:next];
181
+ _orderId = next;
182
+ }
183
+
184
+ - (BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context {
185
+ if(!_orderGroup && !_orderPosition && !_lockFocus && !_orderForward && !_orderBackward) {
186
+ return [super shouldUpdateFocusInContext: context];
187
+ }
188
+
189
+ NSNumber* result = [_focusOrderDelegate shouldUpdateFocusInContext: context];
190
+ if(result == nil) {
191
+ return [super shouldUpdateFocusInContext: context];
192
+ }
193
+
194
+ return result.boolValue;
195
+ }
196
+
197
+ - (void)updateOrderPosition:(NSNumber *)position {
198
+ if(_orderPosition != nil || _orderPosition != position) {
199
+ if(_orderGroup != nil && self.subviews.count > 0 && _isLinked) {
200
+ [[RNCEKVOrderLinking sharedInstance] update:position lastPosition:_orderPosition withOrderKey: _orderGroup withView: self];
201
+ }
202
+ _orderPosition = position;
203
+ }
204
+
205
+ if(_orderPosition == nil && _orderPosition != position) {
206
+ _orderPosition = position;
207
+ }
208
+ }
209
+
83
210
  #ifdef RCT_NEW_ARCH_ENABLED
84
211
  + (ComponentDescriptorProvider)componentDescriptorProvider {
85
212
  return concreteComponentDescriptorProvider<
86
- ExternalKeyboardViewComponentDescriptor>();
213
+ ExternalKeyboardViewComponentDescriptor>();
87
214
  }
88
215
 
89
216
  - (void)prepareForRecycle {
@@ -91,12 +218,6 @@ using namespace facebook::react;
91
218
  [self cleanReferences];
92
219
  }
93
220
 
94
- - (void)willRemoveSubview:(UIView *)subview {
95
- [super willRemoveSubview:subview];
96
- if (_customGroupId && _gIdDelegate) {
97
- [_gIdDelegate clear];
98
- }
99
- }
100
221
 
101
222
  - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
102
223
  NSString *FOCUS = @"focus";
@@ -108,62 +229,86 @@ using namespace facebook::react;
108
229
  - (void)updateProps:(Props::Shared const &)props
109
230
  oldProps:(Props::Shared const &)oldProps {
110
231
  const auto &oldViewProps =
111
- *std::static_pointer_cast<ExternalKeyboardViewProps const>(_props);
232
+ *std::static_pointer_cast<ExternalKeyboardViewProps const>(_props);
112
233
  const auto &newViewProps =
113
- *std::static_pointer_cast<ExternalKeyboardViewProps const>(props);
234
+ *std::static_pointer_cast<ExternalKeyboardViewProps const>(props);
114
235
  [super updateProps:props oldProps:oldProps];
115
-
236
+
116
237
  if (_hasOnFocusChanged != newViewProps.hasOnFocusChanged) {
117
238
  [self setHasOnFocusChanged:newViewProps.hasOnFocusChanged];
118
239
  }
119
-
240
+
241
+ BOOL isLockChanged = [RNCEKVPropHelper isPropChanged:_lockFocus intValue: newViewProps.lockFocus];
242
+ if(isLockChanged) {
243
+ NSNumber* lockValue = [RNCEKVPropHelper unwrapIntValue: newViewProps.lockFocus];
244
+ [self setLockFocus: lockValue];
245
+ }
246
+
120
247
  if (oldViewProps.canBeFocused != newViewProps.canBeFocused) {
121
248
  [self setCanBeFocused:newViewProps.canBeFocused];
122
249
  }
123
-
250
+
124
251
  if (oldViewProps.hasKeyUpPress != newViewProps.hasKeyUpPress) {
125
252
  [self setHasOnPressUp:newViewProps.hasKeyUpPress];
126
253
  }
127
-
254
+
128
255
  if (oldViewProps.hasKeyDownPress != newViewProps.hasKeyDownPress) {
129
256
  [self setHasOnPressDown:newViewProps.hasKeyDownPress];
130
257
  }
131
-
258
+
132
259
  if (oldViewProps.autoFocus != newViewProps.autoFocus) {
133
260
  BOOL hasAutoFocus = newViewProps.autoFocus;
134
261
  [self setAutoFocus:hasAutoFocus];
135
262
  }
136
-
263
+
264
+
265
+ BOOL isIndexChanged = [RNCEKVPropHelper isPropChanged:_orderPosition intValue: newViewProps.orderIndex];
266
+ if(isIndexChanged) {
267
+ NSNumber* position = [RNCEKVPropHelper unwrapIntValue: newViewProps.orderIndex];
268
+ [self updateOrderPosition: position];
269
+ }
270
+
271
+ RKNA_PROP_UPDATE(orderGroup, setOrderGroup, newViewProps);
272
+ RKNA_PROP_UPDATE(orderId, setOrderId, newViewProps);
273
+ RKNA_PROP_UPDATE(orderLeft, setOrderLeft, newViewProps);
274
+ RKNA_PROP_UPDATE(orderRight, setOrderRight, newViewProps);
275
+ RKNA_PROP_UPDATE(orderUp, setOrderUp, newViewProps);
276
+ RKNA_PROP_UPDATE(orderDown, setOrderDown, newViewProps);
277
+ RKNA_PROP_UPDATE(orderForward, setOrderForward, newViewProps);
278
+ RKNA_PROP_UPDATE(orderBackward, setOrderBackward, newViewProps);
279
+ RKNA_PROP_UPDATE(orderLast, setOrderLast, newViewProps);
280
+ RKNA_PROP_UPDATE(orderFirst, setOrderFirst, newViewProps);
281
+
137
282
  if (_enableA11yFocus != newViewProps.enableA11yFocus) {
138
283
  [self setEnableA11yFocus:newViewProps.enableA11yFocus];
139
284
  }
140
-
285
+
141
286
  UIColor *newColor = RCTUIColorFromSharedColor(newViewProps.tintColor);
142
287
  BOOL renewColor = newColor != nil && self.tintColor == nil;
143
288
  BOOL isColorChanged = oldViewProps.tintColor != newViewProps.tintColor;
144
289
  if (isColorChanged || renewColor) {
145
290
  self.tintColor = RCTUIColorFromSharedColor(newViewProps.tintColor);
146
291
  }
147
-
292
+
148
293
  if (oldViewProps.group != newViewProps.group) {
149
294
  [self setIsGroup:newViewProps.group];
150
295
  }
151
-
296
+
152
297
  BOOL isNewGroup =
153
- oldViewProps.groupIdentifier != newViewProps.groupIdentifier;
298
+ oldViewProps.groupIdentifier != newViewProps.groupIdentifier;
154
299
  BOOL recoverCustomGroup =
155
- !self.customGroupId && !newViewProps.groupIdentifier.empty();
300
+ !self.customGroupId && !newViewProps.groupIdentifier.empty();
156
301
  if (isNewGroup || recoverCustomGroup) {
157
302
  if (newViewProps.groupIdentifier.empty() && self.customGroupId != nil) {
158
303
  self.customGroupId = nil;
159
304
  }
160
305
  if (!newViewProps.groupIdentifier.empty()) {
161
306
  NSString *newGroupId =
162
- [NSString stringWithUTF8String:newViewProps.groupIdentifier.c_str()];
307
+ [NSString stringWithUTF8String:newViewProps.groupIdentifier.c_str()];
163
308
  [self setCustomGroupId:newGroupId];
164
309
  }
165
310
  }
166
-
311
+
167
312
  // ToDo RNCEKV-0, refactor, condition for halo effect has side effect, recycle
168
313
  // is a question. The problem that we have to check the condition, (true means
169
314
  // we skip, but when it was false we should reset) and recycle (view is reused
@@ -175,22 +320,22 @@ using namespace facebook::react;
175
320
  [self setIsHaloActive:@(haloState)];
176
321
  }
177
322
  }
178
-
323
+
179
324
  if (_haloExpendX != newViewProps.haloExpendX) {
180
325
  [self setHaloExpendX:newViewProps.haloExpendX];
181
326
  }
182
-
327
+
183
328
  if (_haloExpendY != newViewProps.haloExpendY) {
184
329
  [self setHaloExpendY:newViewProps.haloExpendY];
185
330
  }
186
-
331
+
187
332
  if (_haloCornerRadius != newViewProps.haloCornerRadius) {
188
333
  [self setHaloCornerRadius:newViewProps.haloCornerRadius];
189
334
  }
190
335
  }
191
336
 
192
337
  - (void)mountChildComponentView:
193
- (UIView<RCTComponentViewProtocol> *)childComponentView
338
+ (UIView<RCTComponentViewProtocol> *)childComponentView
194
339
  index:(NSInteger)index {
195
340
  [super mountChildComponentView:childComponentView index:index];
196
341
  }
@@ -226,7 +371,7 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
226
371
 
227
372
  - (void)updateFocus:(UIViewController *)controller {
228
373
  UIView *focusingView = self; // [_focusDelegate getFocusingView];
229
-
374
+
230
375
  if (self.superview != nil && controller != nil) {
231
376
  controller.customFocusView = focusingView;
232
377
  dispatch_async(dispatch_get_main_queue(), ^{
@@ -240,17 +385,18 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
240
385
  - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
241
386
  withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
242
387
  _isFocused = [_focusDelegate isFocusChanged:context];
243
-
388
+
389
+ [_focusOrderDelegate setIsFocused: [_isFocused isEqual:@YES]];
244
390
  if ([self hasOnFocusChanged]) {
245
391
  if (_isFocused != nil) {
246
392
  _isAttachedToWindow = YES;
247
393
  _isAttachedToController = YES;
248
394
  [self onFocusChangeHandler:[_isFocused isEqual:@YES]];
249
395
  }
250
-
396
+
251
397
  return;
252
398
  }
253
-
399
+
254
400
  [super didUpdateFocusInContext:context withAnimationCoordinator:coordinator];
255
401
  }
256
402
 
@@ -312,6 +458,7 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
312
458
 
313
459
  #endif
314
460
 
461
+
315
462
  - (void)a11yFocus {
316
463
  if (!_enableA11yFocus)
317
464
  return;
@@ -324,11 +471,11 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
324
471
  withEvent:(UIPressesEvent *)event {
325
472
  NSDictionary *eventInfo = [_keyboardKeyPressHandler actionDownHandler:presses
326
473
  withEvent:event];
327
-
474
+
328
475
  if (self.hasOnPressUp || self.hasOnPressDown) {
329
476
  [self onKeyDownPressHandler:eventInfo];
330
477
  }
331
-
478
+
332
479
  [super pressesBegan:presses withEvent:event];
333
480
  }
334
481
 
@@ -336,11 +483,11 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
336
483
  withEvent:(UIPressesEvent *)event {
337
484
  NSDictionary *eventInfo = [_keyboardKeyPressHandler actionUpHandler:presses
338
485
  withEvent:event];
339
-
486
+
340
487
  if (self.hasOnPressUp || self.hasOnPressDown) {
341
488
  [self onKeyUpPressHandler:eventInfo];
342
489
  }
343
-
490
+
344
491
  [super pressesEnded:presses withEvent:event];
345
492
  }
346
493
 
@@ -372,20 +519,22 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
372
519
 
373
520
  - (void)didMoveToWindow {
374
521
  [super didMoveToWindow];
375
-
522
+
376
523
  if (self.window) {
377
524
  [[NSNotificationCenter defaultCenter]
378
- addObserver:self
379
- selector:@selector(viewControllerChanged:)
380
- name:@"ViewControllerChangedNotification"
381
- object:nil];
525
+ addObserver:self
526
+ selector:@selector(viewControllerChanged:)
527
+ name:@"ViewControllerChangedNotification"
528
+ object:nil];
529
+ [self onAttached];
382
530
  } else {
383
531
  [[NSNotificationCenter defaultCenter]
384
- removeObserver:self
385
- name:@"ViewControllerChangedNotification"
386
- object:nil];
532
+ removeObserver:self
533
+ name:@"ViewControllerChangedNotification"
534
+ object:nil];
535
+ [self onDetached];
387
536
  }
388
-
537
+
389
538
  if (self.window && !_isAttachedToWindow) {
390
539
  [self onViewAttached];
391
540
  _isAttachedToWindow = YES;
@@ -403,8 +552,18 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
403
552
  - (void)layoutSubviews {
404
553
  [super layoutSubviews];
405
554
  [_haloDelegate displayHalo];
406
-
555
+
407
556
  [_gIdDelegate updateGroupIdentifier];
557
+ // [self setupLayout];
558
+ }
559
+
560
+ - (void)subviewRecycle: (UIView *)subview {
561
+ [_gIdDelegate clearSubview: subview];
562
+ }
563
+
564
+ - (void)willRemoveSubview:(UIView *)subview {
565
+ [super willRemoveSubview:subview];
566
+ [self subviewRecycle: subview];
408
567
  }
409
568
 
410
569
  - (void)viewControllerChanged:(NSNotification *)notification {
@@ -416,15 +575,16 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
416
575
  }
417
576
 
418
577
  - (UIContextMenuConfiguration *)contextMenuInteraction:
419
- (UIContextMenuInteraction *)interaction
578
+ (UIContextMenuInteraction *)interaction
420
579
  configurationForMenuAtLocation:(CGPoint)location
421
- API_AVAILABLE(ios(13.0)) {
580
+ API_AVAILABLE(ios(13.0)) {
422
581
  if (_isFocused != nil && [_isFocused isEqual:@YES]) {
423
582
  [self onContextMenuPressHandler];
424
583
  [self onBubbledContextMenuPressHandler];
425
584
  }
426
-
585
+
427
586
  return nil;
428
587
  }
429
588
 
589
+
430
590
  @end
@@ -10,6 +10,15 @@
10
10
  #define RNCEKVExternalKeyboardViewManager_h
11
11
 
12
12
  #import <React/RCTViewManager.h>
13
+
14
+
15
+ #define RCTK_SIMPLE_PROP(propName, propType, viewClass) \
16
+ RCT_CUSTOM_VIEW_PROPERTY(propName, propType, viewClass) \
17
+ { \
18
+ propType *value = json ? [RCTConvert propType:json] : nil; \
19
+ view.propName = value; \
20
+ }
21
+
13
22
  @interface RNCEKVExternalKeyboardViewManager : RCTViewManager
14
23
  @end
15
24