diff --git a/apps/fluent-tester/macos/Podfile.lock b/apps/fluent-tester/macos/Podfile.lock index 04063b2b44d..32a4e2380f4 100644 --- a/apps/fluent-tester/macos/Podfile.lock +++ b/apps/fluent-tester/macos/Podfile.lock @@ -3,10 +3,10 @@ PODS: - DoubleConversion (1.1.6) - FBLazyVector (0.74.37) - fmt (9.1.0) - - FRNAvatar (0.21.19): + - FRNAvatar (0.22.1): - MicrosoftFluentUI (= 0.13.1) - React - - FRNCallout (0.27.17): + - FRNCallout (0.28.1): - DoubleConversion - glog - RCT-Folly (= 2024.01.01.00) @@ -28,13 +28,13 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - FRNCheckbox (0.17.24): + - FRNCheckbox (0.18.1): - React - - FRNMenuButton (0.13.37): + - FRNMenuButton (0.14.1): - React - - FRNRadioButton (0.21.31): + - FRNRadioButton (0.22.1): - React - - FRNVibrancyView (0.3.5): + - FRNVibrancyView (0.4.1): - React - glog (0.3.5) - MicrosoftFluentUI (0.13.1): @@ -123,8 +123,28 @@ PODS: - fmt (= 9.1.0) - glog - RCTDeprecation (0.74.37) - - RCTFocusZone (0.21.15): + - RCTFocusZone (0.22.1): + - DoubleConversion + - glog + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety - React + - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - RCTRequired (0.74.37) - RCTTypeSafety (0.74.37): - FBLazyVector (= 0.74.37) @@ -1461,17 +1481,17 @@ SPEC CHECKSUMS: DoubleConversion: 5b92c4507c560bb62e7aa1acdf2785ea3ff08b3b FBLazyVector: 5f17e32a39da9146ff32e90cff4e9ebd8b5c3b54 fmt: 03574da4b7ba40de39da59677ca66610ce8c4a02 - FRNAvatar: 52551ea22dbc7be5ecd21abf2baa8b2e3035fc34 - FRNCallout: cc743e926cdb77dfbfb6af71dd955badb32fcd1a - FRNCheckbox: d19d484a1cfdeba6d3f4aacd6084c2ca4c48f92e - FRNMenuButton: c8aef02c683585a9e5a5f5cf34f70e9cf63c0b79 - FRNRadioButton: a40075f901604d571e1ef57c6d062327430aefe2 - FRNVibrancyView: be46aaf2b9fe6ec914ea9c55a3ff7fa7e0e7537d + FRNAvatar: 919ae3fc7d01eee287295360e543d1d2a0432673 + FRNCallout: 54c1ba139dbe454ec473a7fcfb9041acdfeddf33 + FRNCheckbox: 3e478c3229e3a41523a563f9d8e4db5c3bd821cc + FRNMenuButton: 1cdaadd041da62cefba6d095b2a09caac99f38c7 + FRNRadioButton: e0dabd91fb4bd361aa7c0b69b2bd293097bfb8b9 + FRNVibrancyView: 00d49c101e73930d6c714d54747239a4b4077b7a glog: ba31c1afa7dcf1915a109861bccdb4421be6175b MicrosoftFluentUI: dde98d8ed3fc306d9ddd0a6f0bc0c1f24fe5275e RCT-Folly: f47da9a444aae485a0528b3bccf0336156009d60 RCTDeprecation: 88f29fc8fbe38e5bff2e65223eac24450ade59ab - RCTFocusZone: 07730c51b3fc190dba495b849c9b4d9b1919268c + RCTFocusZone: 65eced20dcd7550929acd6750c7cae9783b4b68c RCTRequired: 2736889bc024f33cd9157e06e092ee59848e7f45 RCTTypeSafety: c6f4b53a571b819ef18b3d8c5fa7f57d588102c6 React: 9ddfaba3bb7d30eb3c23b043443543b3b9db8b04 diff --git a/packages/components/FocusZone/RCTFocusZone.podspec b/packages/components/FocusZone/RCTFocusZone.podspec index e94f1268633..9c2b0311d91 100644 --- a/packages/components/FocusZone/RCTFocusZone.podspec +++ b/packages/components/FocusZone/RCTFocusZone.podspec @@ -18,4 +18,6 @@ Pod::Spec.new do |s| s.osx.source_files = "macos/*.{swift,h,m,mm}" s.dependency 'React' + + install_modules_dependencies(s) end diff --git a/packages/components/FocusZone/macos/RCTFocusZoneManager.m b/packages/components/FocusZone/macos/RCTFocusZoneManager.m deleted file mode 100644 index 68b93f136be..00000000000 --- a/packages/components/FocusZone/macos/RCTFocusZoneManager.m +++ /dev/null @@ -1,58 +0,0 @@ -#import "RCTFocusZone.h" -#import "RCTFocusZoneManager.h" -#import -#import - -@implementation RCTFocusZoneManager - -RCT_EXPORT_MODULE() - -RCT_EXPORT_VIEW_PROPERTY(disabled, BOOL) - -RCT_CUSTOM_VIEW_PROPERTY(navigationOrderInRenderOrder, BOOL, RCTFocusZone) -{ - [view setNavigationOrderInRenderOrder:[json boolValue]]; - [[view window] recalculateKeyViewLoop]; -} - -RCT_CUSTOM_VIEW_PROPERTY(focusZoneDirection, NSString, RCTFocusZone) -{ - if ([json isEqualToString:@"bidirectional"]) - { - [view setFocusZoneDirection:FocusZoneDirectionBidirectional]; - } - else if ([json isEqualToString:@"vertical"]) - { - [view setFocusZoneDirection:FocusZoneDirectionVertical]; - } - else if ([json isEqualToString:@"horizontal"]) - { - [view setFocusZoneDirection:FocusZoneDirectionHorizontal]; - } - else if ([json isEqualToString:@"none"]) - { - [view setFocusZoneDirection:FocusZoneDirectionNone]; - } - else - { - [view setFocusZoneDirection:[defaultView focusZoneDirection]]; - } -} - -RCT_EXPORT_VIEW_PROPERTY(navigateAtEnd, NSString) -RCT_EXPORT_VIEW_PROPERTY(tabKeyNavigation, NSString) - -RCT_CUSTOM_VIEW_PROPERTY(defaultTabbableElement, NSNumber, RCTFocusZone) -{ - NSNumber *tag = [RCTConvert NSNumber:json]; - RCTUIManager *manager = [[self bridge] uiManager]; - NSView *defaultResponder = [manager viewForReactTag:tag]; - [view setDefaultResponder:defaultResponder]; -} - -- (RCTView *)view -{ - return [RCTFocusZone new]; -} - -@end diff --git a/packages/components/FocusZone/macos/RCTFocusZoneManager.mm b/packages/components/FocusZone/macos/RCTFocusZoneManager.mm new file mode 100644 index 00000000000..2a732fc5704 --- /dev/null +++ b/packages/components/FocusZone/macos/RCTFocusZoneManager.mm @@ -0,0 +1,153 @@ +#import "RCTFocusZone.h" +#import "RCTFocusZoneManager.h" +#import +#import + +@implementation RCTFocusZoneManager + +RCT_EXPORT_MODULE() + +RCT_EXPORT_VIEW_PROPERTY(disabled, BOOL) + +RCT_CUSTOM_VIEW_PROPERTY(navigationOrderInRenderOrder, BOOL, RCTFocusZone) +{ + [view setNavigationOrderInRenderOrder:[json boolValue]]; + [[view window] recalculateKeyViewLoop]; +} + +RCT_CUSTOM_VIEW_PROPERTY(focusZoneDirection, NSString, RCTFocusZone) +{ + if ([json isEqualToString:@"bidirectional"]) + { + [view setFocusZoneDirection:FocusZoneDirectionBidirectional]; + } + else if ([json isEqualToString:@"vertical"]) + { + [view setFocusZoneDirection:FocusZoneDirectionVertical]; + } + else if ([json isEqualToString:@"horizontal"]) + { + [view setFocusZoneDirection:FocusZoneDirectionHorizontal]; + } + else if ([json isEqualToString:@"none"]) + { + [view setFocusZoneDirection:FocusZoneDirectionNone]; + } + else + { + [view setFocusZoneDirection:[defaultView focusZoneDirection]]; + } +} + +RCT_EXPORT_VIEW_PROPERTY(navigateAtEnd, NSString) +RCT_EXPORT_VIEW_PROPERTY(tabKeyNavigation, NSString) + +RCT_CUSTOM_VIEW_PROPERTY(defaultTabbableElement, NSNumber, RCTFocusZone) +{ + NSNumber *tag = [RCTConvert NSNumber:json]; + RCTUIManager *manager = [[self bridge] uiManager]; + NSView *defaultResponder = [manager viewForReactTag:tag]; + [view setDefaultResponder:defaultResponder]; +} + +- (RCTView *)view +{ + return [RCTFocusZone new]; +} + +@end + +#ifdef RCT_NEW_ARCH_ENABLED + +#include +#include +#include + +#import + +using namespace facebook::react; + +@interface FocusZoneComponentView : RCTViewComponentView +@end + +@implementation FocusZoneComponentView { + RCTFocusZone *_focusZoneView; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + _focusZoneView = [RCTFocusZone new]; + self.contentView = _focusZoneView; + } + return self; +} + +- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps +{ + const auto &newProps = static_cast(*props); + + _focusZoneView.disabled = newProps.disabled; + _focusZoneView.navigationOrderInRenderOrder = newProps.navigationOrderInRenderOrder; + + switch (newProps.navigateAtEnd) { + case RCTFocusZoneNavigateAtEnd::NavigateWrap: + _focusZoneView.navigateAtEnd = @"NavigateWrap"; + break; + case RCTFocusZoneNavigateAtEnd::NavigateContinue: + _focusZoneView.navigateAtEnd = @"NavigateContinue"; + break; + case RCTFocusZoneNavigateAtEnd::NavigateStopAtEnds: + _focusZoneView.navigateAtEnd = @"NavigateStopAtEnds"; + break; + } + + switch (newProps.focusZoneDirection) { + case RCTFocusZoneFocusZoneDirection::Bidirectional: + _focusZoneView.focusZoneDirection = FocusZoneDirectionBidirectional; + break; + case RCTFocusZoneFocusZoneDirection::Vertical: + _focusZoneView.focusZoneDirection = FocusZoneDirectionVertical; + break; + case RCTFocusZoneFocusZoneDirection::Horizontal: + _focusZoneView.focusZoneDirection = FocusZoneDirectionHorizontal; + break; + case RCTFocusZoneFocusZoneDirection::None: + _focusZoneView.focusZoneDirection = FocusZoneDirectionNone; + break; + } + + switch (newProps.tabKeyNavigation) { + case RCTFocusZoneTabKeyNavigation::None: + _focusZoneView.tabKeyNavigation = @"None"; + break; + case RCTFocusZoneTabKeyNavigation::NavigateWrap: + _focusZoneView.tabKeyNavigation = @"NavigateWrap"; + break; + case RCTFocusZoneTabKeyNavigation::NavigateStopAtEnds: + _focusZoneView.tabKeyNavigation = @"NavigateStopAtEnds"; + break; + case RCTFocusZoneTabKeyNavigation::Normal: + _focusZoneView.tabKeyNavigation = @"Normal"; + break; + } + + // defaultTabbableElement is not handled here: resolving a view by React tag + // requires the legacy UIManager and is not supported in the Fabric renderer. + + [super updateProps:props oldProps:oldProps]; +} + +@end + +Class RCTFocusZoneCls(void) +{ + return FocusZoneComponentView.class; +} + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/packages/components/FocusZone/package.json b/packages/components/FocusZone/package.json index c65058cd3a9..5cf8041f432 100644 --- a/packages/components/FocusZone/package.json +++ b/packages/components/FocusZone/package.json @@ -82,6 +82,11 @@ "optional": true } }, + "codegenConfig": { + "name": "RCTFocusZoneSpec", + "type": "components", + "jsSrcsDir": "src" + }, "rnx-kit": { "kitType": "library", "alignDeps": { diff --git a/packages/components/FocusZone/src/FocusZoneNativeComponent.ts b/packages/components/FocusZone/src/FocusZoneNativeComponent.ts index b6c7cf2ae50..58f4da680de 100644 --- a/packages/components/FocusZone/src/FocusZoneNativeComponent.ts +++ b/packages/components/FocusZone/src/FocusZoneNativeComponent.ts @@ -19,6 +19,7 @@ export interface NativeProps extends ViewProps { tabKeyNavigation?: WithDefault<'None' | 'NavigateWrap' | 'NavigateStopAtEnds' | 'Normal', 'None'>; disabled?: boolean; isTabNavigation?: boolean; + navigationOrderInRenderOrder?: boolean; } export default codegenNativeComponent('RCTFocusZone');