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.
- package/README.md +277 -14
- package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegate.java +213 -0
- package/android/src/main/java/com/externalkeyboard/helper/FocusHelper.java +44 -0
- package/android/src/main/java/com/externalkeyboard/helper/Linking/A11yOrderLinking.java +81 -0
- package/android/src/main/java/com/externalkeyboard/helper/Linking/LinkingQueue.java +94 -0
- package/android/src/main/java/com/externalkeyboard/helper/ReactNativeVersionChecker.java +24 -0
- package/android/src/main/java/com/externalkeyboard/services/FocusLinkObserver/FocusLinkObserver.java +131 -0
- package/android/src/main/java/com/externalkeyboard/services/FocusLinkObserver/FocusLinkObserverSingleton.java +20 -0
- package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardView.java +144 -0
- package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardViewManager.java +128 -8
- package/android/src/main/java/com/externalkeyboard/views/KeyboardFocusGroup/KeyboardFocusGroupManager.java +7 -3
- package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapper.java +2 -13
- package/android/src/oldarch/ExternalKeyboardViewManagerSpec.java +25 -0
- package/android/src/oldarch/KeyboardFocusGroupManagerSpec.java +8 -1
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.h +33 -0
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.mm +577 -0
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderProtocol.h +34 -0
- package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.h +1 -0
- package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.mm +9 -0
- package/ios/Helpers/RNCEKVPropHelper/RNCEKVPropHelper.h +22 -0
- package/ios/Helpers/RNCEKVPropHelper/RNCEKVPropHelper.mm +48 -0
- package/ios/Services/RNCEKVFocusLinkObserver.h +27 -0
- package/ios/Services/RNCEKVFocusLinkObserver.mm +101 -0
- package/ios/Services/RNCEKVFocusLinkObserverManager.h +23 -0
- package/ios/Services/RNCEKVFocusLinkObserverManager.mm +30 -0
- package/ios/Services/RNCEKVOrderLinking.h +33 -0
- package/ios/Services/RNCEKVOrderLinking.mm +143 -0
- package/ios/Services/RNCEKVOrderSubscriber.h +24 -0
- package/ios/Services/RNCEKVOrderSubscriber.mm +23 -0
- package/ios/Services/RNCEKVRelashioship.h +28 -0
- package/ios/Services/RNCEKVRelashioship.mm +61 -0
- package/ios/Services/RNCEKVSortedMap.h +22 -0
- package/ios/Services/RNCEKVSortedMap.mm +112 -0
- package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.h +34 -3
- package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.mm +214 -54
- package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.h +9 -0
- package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.mm +80 -55
- package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.h +2 -0
- package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.mm +161 -3
- package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroupManager.mm +6 -0
- package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js +56 -3
- package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
- package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js +30 -0
- package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js.map +1 -0
- package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.js.map +1 -1
- package/lib/commonjs/components/KeyboardFocusGroup/KeyboardFocusGroup.js.map +1 -1
- package/lib/commonjs/context/OrderFocusContext.js +23 -0
- package/lib/commonjs/context/OrderFocusContext.js.map +1 -0
- package/lib/commonjs/index.js +19 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/nativeSpec/ExternalKeyboardViewNativeComponent.js.map +1 -1
- package/lib/commonjs/nativeSpec/KeyboardFocusGroupNativeComponent.js.map +1 -1
- package/lib/commonjs/types/BaseKeyboardView.js +12 -0
- package/lib/commonjs/types/BaseKeyboardView.js.map +1 -1
- package/lib/commonjs/utils/withKeyboardFocus.js +25 -1
- package/lib/commonjs/utils/withKeyboardFocus.js.map +1 -1
- package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js +55 -2
- package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
- package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js +23 -0
- package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.android.js.map +1 -0
- package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.js.map +1 -1
- package/lib/module/components/KeyboardFocusGroup/KeyboardFocusGroup.js.map +1 -1
- package/lib/module/context/OrderFocusContext.js +14 -0
- package/lib/module/context/OrderFocusContext.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/nativeSpec/ExternalKeyboardViewNativeComponent.js.map +1 -1
- package/lib/module/nativeSpec/KeyboardFocusGroupNativeComponent.js.map +1 -1
- package/lib/module/types/BaseKeyboardView.js +11 -1
- package/lib/module/types/BaseKeyboardView.js.map +1 -1
- package/lib/module/utils/withKeyboardFocus.js +25 -1
- package/lib/module/utils/withKeyboardFocus.js.map +1 -1
- package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts +1 -1
- package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts.map +1 -1
- package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.d.ts +24 -0
- package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.d.ts.map +1 -0
- package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.d.ts +1 -0
- package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.d.ts.map +1 -1
- package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.d.ts +2 -0
- package/lib/typescript/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.d.ts.map +1 -1
- package/lib/typescript/src/context/OrderFocusContext.d.ts +10 -0
- package/lib/typescript/src/context/OrderFocusContext.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/nativeSpec/ExternalKeyboardViewNativeComponent.d.ts +12 -0
- package/lib/typescript/src/nativeSpec/ExternalKeyboardViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/nativeSpec/KeyboardFocusGroupNativeComponent.d.ts +1 -0
- package/lib/typescript/src/nativeSpec/KeyboardFocusGroupNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/types/BaseKeyboardView.d.ts +24 -0
- package/lib/typescript/src/types/BaseKeyboardView.d.ts.map +1 -1
- package/lib/typescript/src/utils/withKeyboardFocus.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/BaseKeyboardView/BaseKeyboardView.tsx +77 -4
- package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.android.tsx +39 -0
- package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.ios.tsx +1 -0
- package/src/components/KeyboardFocusGroup/KeyboardFocusGroup.tsx +1 -0
- package/src/context/OrderFocusContext.tsx +25 -0
- package/src/index.tsx +5 -0
- package/src/nativeSpec/ExternalKeyboardViewNativeComponent.ts +12 -0
- package/src/nativeSpec/KeyboardFocusGroupNativeComponent.ts +1 -0
- package/src/types/BaseKeyboardView.ts +26 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
232
|
+
*std::static_pointer_cast<ExternalKeyboardViewProps const>(_props);
|
|
112
233
|
const auto &newViewProps =
|
|
113
|
-
|
|
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
|
-
|
|
298
|
+
oldViewProps.groupIdentifier != newViewProps.groupIdentifier;
|
|
154
299
|
BOOL recoverCustomGroup =
|
|
155
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
525
|
+
addObserver:self
|
|
526
|
+
selector:@selector(viewControllerChanged:)
|
|
527
|
+
name:@"ViewControllerChangedNotification"
|
|
528
|
+
object:nil];
|
|
529
|
+
[self onAttached];
|
|
382
530
|
} else {
|
|
383
531
|
[[NSNotificationCenter defaultCenter]
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
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
|
-
|
|
578
|
+
(UIContextMenuInteraction *)interaction
|
|
420
579
|
configurationForMenuAtLocation:(CGPoint)location
|
|
421
|
-
|
|
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
|
|