react-native-external-keyboard 0.8.4 → 0.9.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegate.java +2 -4
  2. package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegateHost.java +14 -0
  3. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardView.java +2 -1
  4. package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapper.java +150 -3
  5. package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapperManager.java +92 -0
  6. package/android/src/oldarch/TextInputFocusWrapperManagerSpec.java +24 -0
  7. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusGuideDelegate/RNCEKVFocusGuideDelegate.h +1 -1
  8. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.h +5 -0
  9. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.mm +84 -48
  10. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderProtocol.h +6 -8
  11. package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.mm +60 -60
  12. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.h +4 -3
  13. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.mm +110 -87
  14. package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloProtocol.h +1 -1
  15. package/ios/Extensions/RCTEnhancedScrollView+RNCEKVExternalKeyboard.mm +1 -1
  16. package/ios/Extensions/RCTTextInputComponentView+RNCEKVExternalKeyboard.mm +15 -0
  17. package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.h +1 -1
  18. package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.mm +31 -23
  19. package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.h +1 -0
  20. package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.mm +8 -0
  21. package/ios/Helpers/RNCEKVNativeProps/RNCEKVNativeProps.h +123 -0
  22. package/ios/Protocols/RNCEKVCustomFocusEffectProtocol.h +15 -0
  23. package/ios/Protocols/RNCEKVCustomGroudIdProtocol.h +15 -0
  24. package/ios/Views/Base/ContextMenu/RNCEKVViewContextMenuBase.h +33 -0
  25. package/ios/Views/Base/ContextMenu/RNCEKVViewContextMenuBase.mm +83 -0
  26. package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.h +37 -0
  27. package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.mm +88 -0
  28. package/ios/Views/Base/FocusOrderGroup/RNCEKVViewOrderGroupBase.h +49 -0
  29. package/ios/Views/Base/FocusOrderGroup/RNCEKVViewOrderGroupBase.mm +200 -0
  30. package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.h +34 -0
  31. package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.mm +117 -0
  32. package/ios/Views/Base/GroupIdentifier/RNCEKVViewGroupIdentifierBase.h +27 -0
  33. package/ios/Views/Base/GroupIdentifier/RNCEKVViewGroupIdentifierBase.mm +61 -0
  34. package/ios/Views/Base/KeyPress/RNCEKVViewKeyPress.h +30 -0
  35. package/ios/Views/Base/KeyPress/RNCEKVViewKeyPress.mm +82 -0
  36. package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.h +33 -0
  37. package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.mm +102 -0
  38. package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.h +36 -0
  39. package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.mm +63 -0
  40. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.h +75 -74
  41. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.mm +23 -492
  42. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.mm +3 -6
  43. package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.mm +12 -12
  44. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.h +44 -6
  45. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.mm +42 -66
  46. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapperManager.mm +76 -7
  47. package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js +51 -0
  48. package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
  49. package/lib/commonjs/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
  50. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js +51 -0
  51. package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
  52. package/lib/module/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
  53. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.d.ts.map +1 -1
  54. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts +11 -0
  55. package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts.map +1 -1
  56. package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts +16 -1
  57. package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts.map +1 -1
  58. package/package.json +1 -1
  59. package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.tsx +56 -0
  60. package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.ts +11 -0
  61. package/src/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
@@ -16,125 +16,148 @@
16
16
 
17
17
  @implementation RNCEKVHaloDelegate {
18
18
  UIView<RNCEKVHaloProtocol> *_delegate;
19
- UIFocusEffect *_focusEffect;
19
+ UIFocusEffect *_currentEffect;
20
20
  CGFloat _prevHaloExpendX;
21
21
  CGFloat _prevHaloExpendY;
22
22
  CGFloat _prevHaloCornerRadius;
23
23
  CGRect _prevBounds;
24
- BOOL _recycled;
24
+ BOOL _needsApply;
25
25
  }
26
26
 
27
- - (instancetype _Nonnull)initWithView:
28
- (UIView<RNCEKVHaloProtocol> *_Nonnull)delegate {
27
+ - (instancetype _Nonnull)initWithView:(UIView<RNCEKVHaloProtocol> *_Nonnull)delegate {
29
28
  self = [super init];
30
29
  if (self) {
31
30
  _delegate = delegate;
32
- _focusEffect = nil;
33
- _prevBounds = CGRect();
31
+ _currentEffect = nil;
32
+ _prevBounds = CGRectZero;
34
33
  _prevHaloExpendX = 0;
35
34
  _prevHaloExpendY = 0;
36
35
  _prevHaloCornerRadius = 0;
37
- _recycled = true;
36
+ _needsApply = YES;
38
37
  }
39
38
  return self;
40
39
  }
41
40
 
42
- - (BOOL)isHaloHidden {
43
- NSNumber *isHaloActive = [_delegate isHaloActive];
44
- return [isHaloActive isEqual:@NO];
45
- }
41
+ - (UIFocusEffect*) getHalo {
42
+ UIView *focusingView = [_delegate getFocusTargetView];
43
+ UIFocusEffect *prevEffect = _currentEffect;
46
44
 
47
- - (void)displayHalo:(BOOL)force {
48
- _focusEffect = nil;
49
- _recycled = true;
45
+ if (_delegate.isHaloHidden) {
46
+ _currentEffect = [RNCEKVFocusEffectUtility emptyFocusEffect];
47
+ return _currentEffect;
48
+ }
50
49
 
51
- [self displayHalo];
52
- }
50
+ BOOL hasCustomSettings = _delegate.haloExpendX || _delegate.haloExpendY || _delegate.haloCornerRadius;
51
+ if (hasCustomSettings) {
52
+ BOOL boundsChanged = !CGRectEqualToRect(_prevBounds, focusingView.bounds);
53
+ BOOL settingsChanged = _prevHaloExpendX != _delegate.haloExpendX
54
+ || _prevHaloExpendY != _delegate.haloExpendY
55
+ || _prevHaloCornerRadius != _delegate.haloCornerRadius
56
+ || boundsChanged;
53
57
 
54
- - (void)displayHalo {
55
- if (@available(iOS 15.0, *)) {
56
- UIView *focusingView = [_delegate getFocusTargetView];
57
- UIFocusEffect *prevEffect = _focusEffect;
58
-
59
- BOOL isHidden = [self isHaloHidden];
60
-
61
- if (isHidden) {
62
- _focusEffect = [RNCEKVFocusEffectUtility emptyFocusEffect];
63
- }
64
-
65
- BOOL hasHaloSettings = _delegate.haloExpendX || _delegate.haloExpendY ||
66
- _delegate.haloCornerRadius;
67
- BOOL isDifferentBounds =
68
- !CGRectEqualToRect(_prevBounds, focusingView.bounds);
69
- BOOL isDifferent = _prevHaloExpendX != _delegate.haloExpendX ||
70
- _prevHaloExpendY != _delegate.haloExpendY ||
71
- _prevHaloCornerRadius != _delegate.haloCornerRadius ||
72
- isDifferentBounds;
73
-
74
- // ToDo refactor for better halo setup RNCEKV-7, RNCEKV-8
75
- if (!isHidden && hasHaloSettings && isDifferent) {
58
+ if (settingsChanged) {
76
59
  _prevHaloExpendX = _delegate.haloExpendX;
77
60
  _prevHaloExpendY = _delegate.haloExpendY;
78
61
  _prevHaloCornerRadius = _delegate.haloCornerRadius;
79
62
  _prevBounds = focusingView.bounds;
80
-
81
- _focusEffect =
82
- [RNCEKVFocusEffectUtility getFocusEffect:focusingView
83
- withExpandedX:_delegate.haloExpendX
84
- withExpandedY:_delegate.haloExpendY
85
- withCornerRadius:_delegate.haloCornerRadius];
86
- }
87
-
88
- if ((_focusEffect == nil && _recycled) || (_focusEffect != nil && prevEffect != _focusEffect &&
89
- focusingView.focusEffect != _focusEffect)) {
90
- _recycled = false;
91
- [self setFocusEffect: _focusEffect];
63
+
64
+ _currentEffect = [RNCEKVFocusEffectUtility getFocusEffect:focusingView
65
+ withExpandedX:_delegate.haloExpendX
66
+ withExpandedY:_delegate.haloExpendY
67
+ withCornerRadius:_delegate.haloCornerRadius];
92
68
  }
93
69
  }
94
- }
70
+
71
+
72
+
73
+ // [self recomputeCustomEffectIfNeededForView:focusingView];
74
+
75
+
76
+ // BOOL effectChanged = prevEffect != _currentEffect;
77
+ // BOOL pendingNilApply = _currentEffect == nil && _needsApply;
78
+ // BOOL alreadyApplied = !pendingNilApply && focusingView.focusEffect == _currentEffect;
95
79
 
96
- - (void)updateHalo {
97
- if ([self isHaloHidden])
98
- return;
99
- if (@available(iOS 15.0, *)) {
100
- BOOL shouldUpdate = _delegate.haloExpendX || _delegate.haloExpendY ||
101
- _delegate.haloCornerRadius;
102
- if (!shouldUpdate)
103
- return;
104
-
105
- UIView *focusingView = [_delegate getFocusTargetView];
106
- UIFocusEffect *focusEffect =
107
- [RNCEKVFocusEffectUtility getFocusEffect:focusingView
108
- withExpandedX:_delegate.haloExpendX
109
- withExpandedY:_delegate.haloExpendY
110
- withCornerRadius:_delegate.haloCornerRadius];
111
- [self setFocusEffect: focusEffect];
112
- }
80
+ // if (pendingNilApply || (effectChanged && !alreadyApplied)) {
81
+ // _needsApply = NO;
82
+ // [self applyEffect:_currentEffect toView:focusingView];
83
+ // }
84
+ return _currentEffect;
113
85
  }
114
86
 
115
- - (void)setFocusEffect: (UIFocusEffect*) focusEffect {
116
- UIView *focusingView = [_delegate getFocusTargetView];
117
- if (@available(iOS 15.0, *)) {
118
- #ifdef RCT_NEW_ARCH_ENABLED
119
- if([focusingView isKindOfClass: RCTViewComponentView.class]) {
120
- ((RCTViewComponentView*)focusingView).rncekvCustomFocusEffect = focusEffect;
121
- } else {
122
- focusingView.focusEffect = focusEffect;
123
- }
124
- #else
125
- focusingView.focusEffect = focusEffect;
126
- #endif
127
- }
128
- }
87
+ #pragma mark - Public
88
+
89
+ // Called on attach/recycle: forces re-application even if the effect didn't change.
90
+ //- (void)displayHalo:(BOOL)force {
91
+ // if (force) {
92
+ // _currentEffect = nil;
93
+ // _needsApply = YES;
94
+ // }
95
+ // [self displayHalo];
96
+ //}
97
+
98
+ //- (void)displayHalo {
99
+ // if (@available(iOS 15.0, *)) {
100
+ // UIView *focusingView = [_delegate getFocusTargetView];
101
+ // UIFocusEffect *prevEffect = _currentEffect;
102
+ //
103
+ // if ([self isHaloHidden]) {
104
+ // _currentEffect = [RNCEKVFocusEffectUtility emptyFocusEffect];
105
+ // } else {
106
+ // [self recomputeCustomEffectIfNeededForView:focusingView];
107
+ // }
108
+ //
109
+ // BOOL effectChanged = prevEffect != _currentEffect;
110
+ // BOOL pendingNilApply = _currentEffect == nil && _needsApply;
111
+ // BOOL alreadyApplied = !pendingNilApply && focusingView.focusEffect == _currentEffect;
112
+ //
113
+ // if (pendingNilApply || (effectChanged && !alreadyApplied)) {
114
+ // _needsApply = NO;
115
+ // [self applyEffect:_currentEffect toView:focusingView];
116
+ // }
117
+ // }
118
+ //}
119
+
120
+ // Called when halo settings change after mount (expandX/Y, cornerRadius).
121
+ //- (void)updateHalo {
122
+ // [self displayHalo];
123
+ //}
129
124
 
130
- - (void) clear {
131
- [self setFocusEffect: nil];
132
- _focusEffect = nil;
133
- _recycled = true;
134
- _prevBounds = CGRect();
125
+ - (void)clear {
126
+ // [self applyEffect:nil toView:[_delegate getFocusTargetView]];
127
+ _currentEffect = nil;
128
+ // _needsApply = YES;
129
+ _prevBounds = CGRectZero;
135
130
  _prevHaloExpendX = 0;
136
131
  _prevHaloExpendY = 0;
137
132
  _prevHaloCornerRadius = 0;
138
133
  }
139
134
 
135
+ #pragma mark - Private
136
+
137
+ //- (BOOL)isHaloHidden {
138
+ // return [[_delegate isHaloActive] isEqual:@NO];
139
+ //}
140
+
141
+ //- (void)recomputeCustomEffectIfNeededForView:(UIView *)focusingView {
142
+ // BOOL hasCustomSettings = _delegate.haloExpendX || _delegate.haloExpendY || _delegate.haloCornerRadius;
143
+ // if (!hasCustomSettings) return;
144
+ //
145
+ //
146
+ //}
147
+ //
148
+ //- (void)applyEffect:(UIFocusEffect *)effect toView:(UIView *)focusingView {
149
+ // if (!focusingView) return;
150
+ // if (@available(iOS 15.0, *)) {
151
+ //#ifdef RCT_NEW_ARCH_ENABLED
152
+ // if ([focusingView isKindOfClass:RCTViewComponentView.class]) {
153
+ // ((RCTViewComponentView *)focusingView).rncekvCustomFocusEffect = effect;
154
+ // } else {
155
+ // focusingView.focusEffect = effect;
156
+ // }
157
+ //#else
158
+ // focusingView.focusEffect = effect;
159
+ //#endif
160
+ // }
161
+ //}
162
+
140
163
  @end
@@ -10,7 +10,7 @@
10
10
 
11
11
  @protocol RNCEKVHaloProtocol <NSObject>
12
12
 
13
- - (NSNumber *)isHaloActive;
13
+ - (BOOL)isHaloHidden;
14
14
  - (CGFloat) haloCornerRadius;
15
15
  - (CGFloat) haloExpendX;
16
16
  - (CGFloat) haloExpendY;
@@ -47,7 +47,7 @@
47
47
  return scrollView;
48
48
  }
49
49
 
50
-
51
50
  @end
52
51
 
52
+
53
53
  #endif
@@ -8,6 +8,9 @@
8
8
  #import "RCTTextInputComponentView+RNCEKVExternalKeyboard.h"
9
9
  #import <React/RCTBackedTextInputViewProtocol.h>
10
10
  #import <objc/runtime.h>
11
+ #import "RNCEKVCustomFocusEffectProtocol.h"
12
+ #import "RCTUITextField.h"
13
+ #import "RCTUITextView.h"
11
14
 
12
15
  @implementation RCTTextInputComponentView (RNCEKVExternalKeyboard)
13
16
 
@@ -26,5 +29,17 @@
26
29
 
27
30
  @end
28
31
 
32
+ @implementation RCTUITextField (RNCEKVExternalKeyboard)
33
+ - (UIFocusEffect*)focusEffect {
34
+ id superParent = self.superview.superview;
35
+ if (superParent != nil && [superParent conformsToProtocol:@protocol(RNCEKVCustomFocusEffectProtocol)]) {
36
+ id<RNCEKVCustomFocusEffectProtocol> parent = (id<RNCEKVCustomFocusEffectProtocol>)superParent;
37
+ return [parent customFocusEffect];
38
+ }
39
+
40
+ return [super focusEffect];
41
+ }
42
+ @end
43
+
29
44
  #endif
30
45
 
@@ -15,7 +15,7 @@
15
15
  @interface RCTViewComponentView (RNCEKVExternalKeyboard)
16
16
 
17
17
  @property (nonatomic, copy, nullable) NSString *rncekvCustomGroup;
18
- @property (nonatomic, copy, nullable) UIFocusEffect *rncekvCustomFocusEffect;
18
+ //@property (nonatomic, copy, nullable) UIFocusEffect *rncekvCustomFocusEffect;
19
19
 
20
20
  @end
21
21
 
@@ -8,44 +8,52 @@
8
8
  #ifdef RCT_NEW_ARCH_ENABLED
9
9
 
10
10
  #import <Foundation/Foundation.h>
11
-
11
+ #import "RNCEKVCustomFocusEffectProtocol.h"
12
12
  #import "RCTViewComponentView+RNCEKVExternalKeyboard.h"
13
+ #import "RNCEKVCustomGroudIdProtocol.h"
13
14
 
14
- #import <objc/runtime.h>
15
- static const void *RNCEKVCustomGroupKey = &RNCEKVCustomGroupKey;
16
- static const void *RNCEKVCustomFocusEffect = &RNCEKVCustomFocusEffect;
15
+ //#import <objc/runtime.h>
16
+ //static const void *RNCEKVCustomGroupKey = &RNCEKVCustomGroupKey;
17
+ //static const void *RNCEKVCustomFocusEffect = &RNCEKVCustomFocusEffect;
17
18
 
18
19
  @implementation RCTViewComponentView (RNCEKVExternalKeyboard)
19
20
 
20
- - (NSString *)rncekvCustomGroup {
21
- return objc_getAssociatedObject(self, RNCEKVCustomGroupKey);
22
- }
23
-
24
- - (void)setRncekvCustomGroup:(NSString *)rncekvCustomGroup {
25
- objc_setAssociatedObject(self, RNCEKVCustomGroupKey, rncekvCustomGroup, OBJC_ASSOCIATION_COPY_NONATOMIC);
26
- }
21
+ //- (NSString *)rncekvCustomGroup {
22
+ // return objc_getAssociatedObject(self, RNCEKVCustomGroupKey);
23
+ //}
24
+ //
25
+ //- (void)setRncekvCustomGroup:(NSString *)rncekvCustomGroup {
26
+ // objc_setAssociatedObject(self, RNCEKVCustomGroupKey, rncekvCustomGroup, OBJC_ASSOCIATION_COPY_NONATOMIC);
27
+ //}
27
28
 
28
- - (NSString *)rncekvCustomFocusEffect {
29
- return objc_getAssociatedObject(self, RNCEKVCustomFocusEffect);
30
- }
29
+ //- (NSString *)rncekvCustomFocusEffect {
30
+ // return objc_getAssociatedObject(self, RNCEKVCustomFocusEffect);
31
+ //}
31
32
 
32
- - (void)setRncekvCustomFocusEffect:(NSString *)rncekvCustomFocusEffect {
33
- objc_setAssociatedObject(self, RNCEKVCustomFocusEffect, rncekvCustomFocusEffect, OBJC_ASSOCIATION_COPY_NONATOMIC);
34
- }
33
+ //- (void)setRncekvCustomFocusEffect:(NSString *)rncekvCustomFocusEffect {
34
+ // objc_setAssociatedObject(self, RNCEKVCustomFocusEffect, rncekvCustomFocusEffect, OBJC_ASSOCIATION_COPY_NONATOMIC);
35
+ //}
35
36
 
36
37
  - (NSString *)focusGroupIdentifier {
37
- NSString* rncekv = [self rncekvCustomGroup];
38
- if(rncekv) {
39
- return rncekv;
38
+ if ([self.superview conformsToProtocol:@protocol(RNCEKVCustomGroudIdProtocol)]) {
39
+ id<RNCEKVCustomGroudIdProtocol> parent = (id<RNCEKVCustomGroudIdProtocol>)self.superview;
40
+ NSString* groupId = [parent customGroupIdentifier];
41
+ if(groupId != nil) {
42
+ return groupId;
43
+ }
40
44
  }
45
+
41
46
  return [super focusGroupIdentifier];
42
47
  }
43
48
 
44
49
 
45
50
  - (UIFocusEffect*)focusEffect {
46
- UIFocusEffect* rncekv = [self rncekvCustomFocusEffect];
47
- if(rncekv) {
48
- return rncekv;
51
+ if ([self.superview conformsToProtocol:@protocol(RNCEKVCustomFocusEffectProtocol)]) {
52
+ id<RNCEKVCustomFocusEffectProtocol> parent = (id<RNCEKVCustomFocusEffectProtocol>)self.superview;
53
+ UIFocusEffect* effect = [parent customFocusEffect];
54
+ if(effect != nil) {
55
+ return effect;
56
+ }
49
57
  }
50
58
 
51
59
  return [super focusEffect];
@@ -12,6 +12,7 @@
12
12
 
13
13
  @interface UIViewController (RNCEKVExternalKeyboard)
14
14
  @property (nonatomic, strong) UIView *rncekvCustomFocusView;
15
+ - (void)rncekvFocusView:(UIView *)view;
15
16
  @end
16
17
 
17
18
  #endif /* UIViewController_RNCEKVExternalKeyboard_h */
@@ -41,6 +41,14 @@ static char kCustomFocusViewKey;
41
41
  [[NSNotificationCenter defaultCenter] postNotificationName:@"ViewControllerChangedNotification" object:self];
42
42
  }
43
43
 
44
+ - (void)rncekvFocusView:(UIView *)view {
45
+ self.rncekvCustomFocusView = view;
46
+ dispatch_async(dispatch_get_main_queue(), ^{
47
+ [self setNeedsFocusUpdate];
48
+ [self updateFocusIfNeeded];
49
+ });
50
+ }
51
+
44
52
  - (NSArray<id<UIFocusEnvironment>> *)keyboardedPreferredFocusEnvironments {
45
53
  NSArray<id<UIFocusEnvironment>> *originalEnvironments = [self keyboardedPreferredFocusEnvironments];
46
54
 
@@ -0,0 +1,123 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ namespace RNCEKV {
6
+
7
+ struct OrderProps {
8
+ std::string orderGroup{};
9
+ int orderIndex{0};
10
+ int lockFocus{0};
11
+ std::string orderId{};
12
+ std::string orderLeft{};
13
+ std::string orderRight{};
14
+ std::string orderUp{};
15
+ std::string orderDown{};
16
+ std::string orderForward{};
17
+ std::string orderBackward{};
18
+ std::string orderFirst{};
19
+ std::string orderLast{};
20
+
21
+ template <typename T>
22
+ static OrderProps from(const T &props) {
23
+ return OrderProps{
24
+ props.orderGroup,
25
+ props.orderIndex,
26
+ props.lockFocus,
27
+ props.orderId,
28
+ props.orderLeft,
29
+ props.orderRight,
30
+ props.orderUp,
31
+ props.orderDown,
32
+ props.orderForward,
33
+ props.orderBackward,
34
+ props.orderFirst,
35
+ props.orderLast,
36
+ };
37
+ }
38
+ };
39
+
40
+
41
+
42
+ struct HaloProps {
43
+ bool haloEffect{true};
44
+ double haloExpendX{0};
45
+ double haloExpendY{0};
46
+ double haloCornerRadius{0};
47
+ facebook::react::SharedColor tintColor{};
48
+
49
+ template <typename T>
50
+ static HaloProps from(const T &props) {
51
+ return HaloProps{
52
+ props.haloEffect,
53
+ props.haloExpendX,
54
+ props.haloExpendY,
55
+ props.haloCornerRadius,
56
+ props.tintColor,
57
+ };
58
+ }
59
+ };
60
+
61
+ struct GroupIdentifierProps {
62
+ std::string groupIdentifier{};
63
+
64
+ template <typename T>
65
+ static GroupIdentifierProps from(const T &props) {
66
+ return GroupIdentifierProps{
67
+ props.groupIdentifier,
68
+ };
69
+ }
70
+ };
71
+
72
+ struct FocusProps {
73
+ bool canBeFocused{false};
74
+ bool hasOnFocusChanged{false};
75
+
76
+ template <typename T>
77
+ static FocusProps from(const T &props) {
78
+ return FocusProps{
79
+ props.canBeFocused,
80
+ props.hasOnFocusChanged
81
+ };
82
+ }
83
+ };
84
+
85
+
86
+ struct ContextMenuProps {
87
+ bool enableContextMenu{false};
88
+
89
+ template <typename T>
90
+ static ContextMenuProps from(const T &props) {
91
+ return ContextMenuProps{
92
+ props.enableContextMenu,
93
+ };
94
+ }
95
+ };
96
+
97
+ struct AutoFocusProps {
98
+ bool autoFocus{false};
99
+ bool enableA11yFocus{false};
100
+
101
+ template <typename T>
102
+ static AutoFocusProps from(const T &props) {
103
+ return AutoFocusProps{
104
+ props.autoFocus,
105
+ props.enableA11yFocus,
106
+ };
107
+ }
108
+ };
109
+
110
+ struct KeyPressProps {
111
+ bool hasKeyDownPress{false};
112
+ bool hasKeyUpPress{false};
113
+
114
+ template <typename T>
115
+ static KeyPressProps from(const T &props) {
116
+ return KeyPressProps{
117
+ props.hasKeyDownPress,
118
+ props.hasKeyUpPress,
119
+ };
120
+ }
121
+ };
122
+
123
+ } // namespace RNCEKV
@@ -0,0 +1,15 @@
1
+ //
2
+ // RNCEKVCustomFocusEffectProtocol.h
3
+ // Pods
4
+ //
5
+ // Created by Artur Kalach on 08/04/2026.
6
+ //
7
+
8
+ #ifndef RNCEKVCustomFocusEffectProtocol_h
9
+ #define RNCEKVCustomFocusEffectProtocol_h
10
+
11
+ @protocol RNCEKVCustomFocusEffectProtocol <NSObject>
12
+ - (UIFocusEffect*)customFocusEffect;
13
+ @end
14
+
15
+ #endif /* RNCEKVCustomFocusEffectProtocol_h */
@@ -0,0 +1,15 @@
1
+ //
2
+ // RNCEKVCustomGroudIdProtocol.h
3
+ // Pods
4
+ //
5
+ // Created by Artur Kalach on 09/04/2026.
6
+ //
7
+
8
+ #ifndef RNCEKVCustomGroudIdProtocol_h
9
+ #define RNCEKVCustomGroudIdProtocol_h
10
+
11
+ @protocol RNCEKVCustomGroudIdProtocol <NSObject>
12
+ - (NSString*)customGroupIdentifier;
13
+ @end
14
+
15
+ #endif /* RNCEKVCustomGroudIdProtocol_h */
@@ -0,0 +1,33 @@
1
+ //
2
+ // RNCEKVViewContextMenuBase.h
3
+ // Pods
4
+ //
5
+ // Created by Artur Kalach on 09/04/2026.
6
+ //
7
+
8
+ #ifndef RNCEKVViewContextMenuBase_h
9
+ #define RNCEKVViewContextMenuBase_h
10
+
11
+
12
+ #import "RNCEKVViewFocusChangeBase.h"
13
+
14
+ #ifdef RCT_NEW_ARCH_ENABLED
15
+ #import "RNCEKVNativeProps.h"
16
+ #endif
17
+
18
+ @interface RNCEKVViewContextMenuBase : RNCEKVViewFocusChangeBase<UIContextMenuInteractionDelegate>
19
+
20
+ @property (nonatomic, assign) BOOL enableContextMenu;
21
+
22
+ #ifdef RCT_NEW_ARCH_ENABLED
23
+ - (void)updateContextMenuProps:(const RNCEKV::ContextMenuProps &)oldProps
24
+ newProps:(const RNCEKV::ContextMenuProps &)newProps;
25
+ #endif
26
+
27
+ - (void)onContextMenuPressHandler;
28
+ - (void)onBubbledContextMenuPressHandler;
29
+
30
+ @end
31
+
32
+
33
+ #endif /* RNCEKVViewContextMenuBase_h */
@@ -0,0 +1,83 @@
1
+ //
2
+ // RNCEKVViewContextMenuBase.m
3
+ // react-native-external-keyboard
4
+ //
5
+ // Created by Artur Kalach on 09/04/2026.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+
11
+
12
+ #import "RNCEKVViewContextMenuBase.h"
13
+
14
+ #ifdef RCT_NEW_ARCH_ENABLED
15
+ #import "RNCEKVNativeProps.h"
16
+ #import "RNCEKVFabricEventHelper.h"
17
+ #endif
18
+
19
+ @implementation RNCEKVViewContextMenuBase {
20
+ UIContextMenuInteraction *_contextMenuInteraction;
21
+ }
22
+
23
+ - (void)cleanReferences {
24
+ _enableContextMenu = false;
25
+ [self updateContextMenuRegistration];
26
+ }
27
+
28
+ - (void)setEnableContextMenu:(BOOL)enableContextMenu {
29
+ _enableContextMenu = enableContextMenu;
30
+ [self updateContextMenuRegistration];
31
+ }
32
+
33
+ - (void)updateContextMenuRegistration {
34
+ if (@available(iOS 13.0, *)) {
35
+ BOOL shouldRegister = _enableContextMenu &&
36
+ self.isKeyboardFocused;
37
+
38
+ if (shouldRegister && _contextMenuInteraction == nil) {
39
+ _contextMenuInteraction =
40
+ [[UIContextMenuInteraction alloc] initWithDelegate:self];
41
+ [self addInteraction:_contextMenuInteraction];
42
+ }
43
+
44
+ if (!shouldRegister && _contextMenuInteraction != nil) {
45
+ [self removeInteraction:_contextMenuInteraction];
46
+ _contextMenuInteraction = nil;
47
+ }
48
+ }
49
+ }
50
+
51
+ - (void)onFocusChangeHandler:(BOOL)isFocused {
52
+ [super onFocusChangeHandler: isFocused];
53
+ [self updateContextMenuRegistration];
54
+ }
55
+
56
+ - (UIContextMenuConfiguration *)contextMenuInteraction:
57
+ (UIContextMenuInteraction *)interaction
58
+ configurationForMenuAtLocation:(CGPoint)location
59
+ API_AVAILABLE(ios(13.0)) {
60
+ if (self.isKeyboardFocused) {
61
+ [self onContextMenuPressHandler];
62
+ [self onBubbledContextMenuPressHandler];
63
+ }
64
+
65
+ return nil;
66
+ }
67
+
68
+ - (void)onContextMenuPressHandler {}
69
+ - (void)onBubbledContextMenuPressHandler {}
70
+
71
+ #ifdef RCT_NEW_ARCH_ENABLED
72
+ - (void)updateContextMenuProps:(const RNCEKV::ContextMenuProps &)oldProps
73
+ newProps:(const RNCEKV::ContextMenuProps &)newProps {
74
+ if (oldProps.enableContextMenu != newProps.enableContextMenu) {
75
+ [self setEnableContextMenu: newProps.enableContextMenu];
76
+ [self updateContextMenuRegistration];
77
+ }
78
+ }
79
+
80
+ #endif
81
+
82
+
83
+ @end