react-native-windows 0.74.29 → 0.74.30

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 (70) hide show
  1. package/Libraries/Components/Button.windows.js +9 -0
  2. package/Libraries/Components/Pressable/Pressable.windows.js +9 -0
  3. package/Libraries/Components/TextInput/TextInput.windows.js +11 -1
  4. package/Libraries/Components/Touchable/TouchableBounce.windows.js +225 -0
  5. package/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js +373 -0
  6. package/Libraries/Components/Touchable/TouchableOpacity.windows.js +7 -0
  7. package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +10 -0
  8. package/Libraries/Components/View/View.windows.js +11 -1
  9. package/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
  10. package/Libraries/Components/View/ViewAccessibility.windows.js +5 -2
  11. package/Libraries/Components/View/ViewPropTypes.windows.js +3 -0
  12. package/Libraries/Image/Image.windows.js +7 -0
  13. package/Libraries/Text/Text.windows.js +11 -1
  14. package/Libraries/Text/TextProps.windows.js +3 -0
  15. package/Microsoft.ReactNative/CompositionComponentView.idl +13 -1
  16. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +1 -2
  17. package/Microsoft.ReactNative/Fabric/ComponentView.h +1 -1
  18. package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +0 -5
  19. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +293 -9
  20. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +28 -1
  21. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +13 -32
  22. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +1 -3
  23. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +1 -1
  24. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +2 -1
  25. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +18 -5
  26. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +1 -1
  27. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +191 -329
  28. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +3 -61
  29. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +66 -0
  30. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.h +52 -0
  31. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +21 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +7 -4
  33. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +79 -19
  34. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -6
  35. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +71 -17
  36. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +16 -0
  37. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +1 -1
  38. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +1 -1
  39. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +62 -33
  40. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +5 -2
  41. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +1 -6
  42. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +0 -3
  43. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +0 -2
  44. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +5 -0
  45. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +19 -1
  46. package/Microsoft.ReactNative/ReactNativeHost.cpp +5 -0
  47. package/Microsoft.ReactNative/ReactNativeIsland.idl +5 -1
  48. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  49. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h +253 -0
  50. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h +799 -0
  51. package/Shared/Shared.vcxitems +3 -2
  52. package/Shared/Shared.vcxitems.filters +2 -3
  53. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +204 -0
  54. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +287 -0
  55. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +192 -0
  56. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +216 -0
  57. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +242 -0
  58. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +259 -0
  59. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +226 -0
  60. package/codegen/react/components/rnwcore/InputAccessory.g.h +192 -0
  61. package/codegen/react/components/rnwcore/ModalHostView.g.h +271 -0
  62. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +238 -0
  63. package/codegen/react/components/rnwcore/SafeAreaView.g.h +189 -0
  64. package/codegen/react/components/rnwcore/Switch.g.h +255 -0
  65. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +192 -0
  66. package/just-task.js +1 -1
  67. package/package.json +1 -1
  68. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentDescriptor.h +0 -39
  69. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.cpp +0 -18
  70. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.h +0 -39
@@ -0,0 +1,66 @@
1
+
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT License.
4
+
5
+ #pragma once
6
+
7
+ #include "PortalComponentView.h"
8
+
9
+ #include "Composition.PortalComponentView.g.cpp"
10
+
11
+ namespace winrt::Microsoft::ReactNative::Composition::implementation {
12
+
13
+ PortalComponentView::PortalComponentView(
14
+ const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
15
+ facebook::react::Tag tag,
16
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext,
17
+ winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder)
18
+ : base_type(tag, reactContext, builder) {
19
+ m_rootComponentView = winrt::make_self<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>(
20
+ compContext, *this, reactContext);
21
+ }
22
+
23
+ PortalComponentView::~PortalComponentView() {}
24
+
25
+ winrt::Microsoft::ReactNative::Composition::RootComponentView PortalComponentView::ContentRoot() const noexcept {
26
+ return *m_rootComponentView;
27
+ }
28
+
29
+ void PortalComponentView::MountChildComponentView(
30
+ const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
31
+ uint32_t index) noexcept {
32
+ m_rootComponentView->MountChildComponentView(childComponentView, index);
33
+ }
34
+
35
+ void PortalComponentView::UnmountChildComponentView(
36
+ const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
37
+ uint32_t index) noexcept {
38
+ m_rootComponentView->UnmountChildComponentView(childComponentView, index);
39
+ }
40
+
41
+ const winrt::Microsoft::ReactNative::IComponentProps PortalComponentView::userProps(
42
+ facebook::react::Props::Shared const &props) noexcept {
43
+ const auto &abiViewProps = *std::static_pointer_cast<const ::Microsoft::ReactNative::AbiViewProps>(props);
44
+ return abiViewProps.UserProps();
45
+ }
46
+
47
+ void PortalComponentView::updateProps(
48
+ facebook::react::Props::Shared const &props,
49
+ facebook::react::Props::Shared const &oldProps) noexcept {
50
+ m_rootComponentView->updateProps(props, oldProps);
51
+ base_type::updateProps(props, oldProps);
52
+ }
53
+
54
+ void PortalComponentView::updateLayoutMetrics(
55
+ facebook::react::LayoutMetrics const &layoutMetrics,
56
+ facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
57
+ m_rootComponentView->updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
58
+ base_type::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
59
+ }
60
+
61
+ void PortalComponentView::FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept {
62
+ m_rootComponentView->FinalizeUpdates(updateMask);
63
+ base_type::FinalizeUpdates(updateMask);
64
+ }
65
+
66
+ } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -0,0 +1,52 @@
1
+
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT License.
4
+
5
+ #pragma once
6
+
7
+ #include <Fabric/ComponentView.h>
8
+ #include <Microsoft.ReactNative.Cxx/ReactContext.h>
9
+ #include "RootComponentView.h"
10
+
11
+ #include "Composition.PortalComponentView.g.h"
12
+
13
+ namespace Microsoft::ReactNative {
14
+ struct CompContext;
15
+ } // namespace Microsoft::ReactNative
16
+
17
+ namespace winrt::Microsoft::ReactNative::Composition::implementation {
18
+
19
+ struct PortalComponentView
20
+ : public PortalComponentViewT<PortalComponentView, winrt::Microsoft::ReactNative::implementation::ComponentView> {
21
+ PortalComponentView(
22
+ const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
23
+ facebook::react::Tag tag,
24
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext,
25
+ winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder);
26
+ virtual ~PortalComponentView();
27
+
28
+ winrt::Microsoft::ReactNative::Composition::RootComponentView ContentRoot() const noexcept;
29
+
30
+ void MountChildComponentView(
31
+ const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
32
+ uint32_t index) noexcept override;
33
+ void UnmountChildComponentView(
34
+ const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
35
+ uint32_t index) noexcept override;
36
+
37
+ const winrt::Microsoft::ReactNative::IComponentProps userProps(
38
+ facebook::react::Props::Shared const &props) noexcept override;
39
+ void updateProps(facebook::react::Props::Shared const &props, facebook::react::Props::Shared const &oldProps) noexcept
40
+ override;
41
+
42
+ void updateLayoutMetrics(
43
+ facebook::react::LayoutMetrics const &layoutMetrics,
44
+ facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
45
+
46
+ void FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept override;
47
+
48
+ private:
49
+ winrt::com_ptr<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView> m_rootComponentView;
50
+ };
51
+
52
+ } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -5,6 +5,7 @@
5
5
  #include "ReactCompositionViewComponentBuilder.h"
6
6
  #include <Fabric/Composition/CompositionViewComponentView.h>
7
7
  #include <Fabric/Composition/ContentIslandComponentView.h>
8
+ #include <Fabric/Composition/PortalComponentView.h>
8
9
  #include <strsafe.h>
9
10
  #include "CompositionContextHelper.h"
10
11
  #include "DynamicWriter.h"
@@ -111,6 +112,26 @@ void ReactCompositionViewComponentBuilder::SetContentIslandComponentViewInitiali
111
112
  };
112
113
  }
113
114
 
115
+ void ReactCompositionViewComponentBuilder::SetPortalComponentViewInitializer(
116
+ const PortalComponentViewInitializer &initializer) noexcept {
117
+ m_fnCreateView = [initializer](
118
+ const IReactContext &reactContext,
119
+ int32_t tag,
120
+ const Experimental::ICompositionContext &context,
121
+ ComponentViewFeatures /*features*/,
122
+ ReactCompositionViewComponentBuilder &builder)
123
+ -> winrt::Microsoft::ReactNative::Composition::PortalComponentView {
124
+ auto view = winrt::make<winrt::Microsoft::ReactNative::Composition::implementation::PortalComponentView>(
125
+ context, tag, reactContext, &builder);
126
+ initializer(view);
127
+ return view;
128
+ };
129
+ m_descriptorConstructorFactory = []() {
130
+ return &facebook::react::concreteComponentDescriptorConstructor<
131
+ ::Microsoft::ReactNative::AbiViewComponentDescriptor>;
132
+ };
133
+ }
134
+
114
135
  // (Object handle, Microsoft.ReactNative.IComponentState state) => void
115
136
  // void ReactCompositionViewComponentBuilder::SetStateUpdater(StateUpdater impl) noexcept {
116
137
  // m_stateUpdater = impl;
@@ -12,10 +12,12 @@
12
12
 
13
13
  namespace winrt::Microsoft::ReactNative::Composition {
14
14
 
15
- struct ReactCompositionViewComponentBuilder : winrt::implements<
16
- ReactCompositionViewComponentBuilder,
17
- IReactViewComponentBuilder,
18
- Composition::IReactCompositionViewComponentBuilder> {
15
+ struct ReactCompositionViewComponentBuilder
16
+ : winrt::implements<
17
+ ReactCompositionViewComponentBuilder,
18
+ IReactViewComponentBuilder,
19
+ Composition::IReactCompositionViewComponentBuilder,
20
+ Composition::Experimental::IReactCompositionViewComponentInternalBuilder> {
19
21
  ReactCompositionViewComponentBuilder() noexcept;
20
22
 
21
23
  public: // IReactViewComponentBuilder
@@ -42,6 +44,7 @@ struct ReactCompositionViewComponentBuilder : winrt::implements<
42
44
  public: // Composition::IReactCompositionViewComponentBuilder
43
45
  void SetViewComponentViewInitializer(const ViewComponentViewInitializer &initializer) noexcept;
44
46
  void SetContentIslandComponentViewInitializer(const ComponentIslandComponentViewInitializer &initializer) noexcept;
47
+ void SetPortalComponentViewInitializer(const PortalComponentViewInitializer &initializer) noexcept;
45
48
  void SetCreateVisualHandler(CreateVisualDelegate impl) noexcept;
46
49
  void SetViewFeatures(ComponentViewFeatures viewFeatures) noexcept;
47
50
  void SetVisualToMountChildrenIntoHandler(VisualToMountChildrenIntoDelegate impl) noexcept;
@@ -127,21 +127,39 @@ ReactNativeIsland::ReactNativeIsland(const winrt::Microsoft::UI::Composition::Co
127
127
  InitTextScaleMultiplier();
128
128
  }
129
129
 
130
- // Constructor to initialize ReactNativeIsland with context and componentView
131
130
  ReactNativeIsland::ReactNativeIsland(
132
- const winrt::Microsoft::UI::Composition::Compositor &compositor,
133
- winrt::Microsoft::ReactNative::IReactContext context,
134
- winrt::Microsoft::ReactNative::ComponentView componentView) noexcept
135
- : m_compositor(compositor),
136
- m_context(context),
131
+ const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portal) noexcept
132
+ : m_compositor(portal.ContentRoot().Compositor()),
133
+ m_context(portal.ReactContext()),
137
134
  m_layoutConstraints({{0, 0}, {0, 0}, winrt::Microsoft::ReactNative::LayoutDirection::Undefined}),
138
135
  m_isFragment(true) {
139
- m_rootTag = componentView.Tag();
136
+ m_portal = winrt::make_weak(portal);
137
+
138
+ auto trueRoot =
139
+ winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::PortalComponentView>(portal)
140
+ ->rootComponentView();
141
+ while (auto p = trueRoot->Portal()) {
142
+ trueRoot = winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::PortalComponentView>(p)
143
+ ->rootComponentView();
144
+ };
145
+ m_rootTag = trueRoot->Tag();
146
+
140
147
  InitTextScaleMultiplier();
141
- AddFragmentCompositionEventHandler(context, componentView);
148
+ AddFragmentCompositionEventHandler(m_context.Handle(), portal.ContentRoot());
149
+ auto selfPortal = winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>(
150
+ portal.ContentRoot());
151
+ selfPortal->ReactNativeIsland(*this);
152
+ NotifySizeChanged();
153
+ selfPortal->start(*this);
154
+ }
155
+
156
+ winrt::Microsoft::ReactNative::ReactNativeIsland ReactNativeIsland::CreatePortal(
157
+ const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portal) noexcept {
158
+ return winrt::make<ReactNativeIsland>(portal);
142
159
  }
143
160
 
144
- ReactNativeIsland::ReactNativeIsland() noexcept : ReactNativeIsland(nullptr) {}
161
+ ReactNativeIsland::ReactNativeIsland() noexcept
162
+ : ReactNativeIsland(winrt::Microsoft::UI::Composition::Compositor{nullptr}) {}
145
163
 
146
164
  ReactNativeIsland::~ReactNativeIsland() noexcept {
147
165
  #ifdef USE_WINUI3
@@ -159,14 +177,20 @@ ReactNativeIsland::~ReactNativeIsland() noexcept {
159
177
  assert(m_uiDispatcher.HasThreadAccess());
160
178
  UninitRootView();
161
179
  }
180
+
181
+ if (m_island) {
182
+ m_island.Close();
183
+ }
162
184
  }
163
185
 
164
186
  ReactNative::IReactViewHost ReactNativeIsland::ReactViewHost() noexcept {
165
187
  return m_reactViewHost;
166
188
  }
167
189
 
168
- void ReactNativeIsland::ReactViewHost(winrt::Microsoft::ReactNative::IReactViewHost const &value) noexcept {
169
- assert(!m_isFragment); // make sure this isn't a FragmentIsalnd
190
+ void ReactNativeIsland::ReactViewHost(winrt::Microsoft::ReactNative::IReactViewHost const &value) {
191
+ if (m_isFragment)
192
+ winrt::throw_hresult(E_ACCESSDENIED);
193
+
170
194
  if (m_reactViewHost == value) {
171
195
  return;
172
196
  }
@@ -217,6 +241,8 @@ void ReactNativeIsland::AddRenderedVisual(
217
241
 
218
242
  void ReactNativeIsland::RemoveRenderedVisual(
219
243
  const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual) noexcept {
244
+ if (m_isFragment)
245
+ return;
220
246
  assert(m_hasRenderedVisual);
221
247
  InternalRootVisual().Remove(visual);
222
248
  m_hasRenderedVisual = false;
@@ -442,7 +468,7 @@ void ReactNativeIsland::InitRootView(
442
468
 
443
469
  m_context = winrt::Microsoft::ReactNative::ReactContext(std::move(context));
444
470
  m_reactViewOptions = std::move(viewOptions);
445
- m_CompositionEventHandler = std::make_shared<::Microsoft::ReactNative::CompositionEventHandler>(m_context, *this, -1);
471
+ m_CompositionEventHandler = std::make_shared<::Microsoft::ReactNative::CompositionEventHandler>(m_context, *this);
446
472
  m_CompositionEventHandler->Initialize();
447
473
 
448
474
  UpdateRootViewInternal();
@@ -457,15 +483,13 @@ void ReactNativeIsland::AddFragmentCompositionEventHandler(
457
483
  .Get(winrt::Microsoft::ReactNative::ReactDispatcherHelper::UIDispatcherProperty())
458
484
  .try_as<IReactDispatcher>();
459
485
  VerifyElseCrash(m_uiDispatcher.HasThreadAccess());
460
- VerifyElseCrash(m_rootTag != -1);
461
486
  auto uiManager = ::Microsoft::ReactNative::FabricUIManager::FromProperties(
462
487
  winrt::Microsoft::ReactNative::ReactPropertyBag(context.Properties()));
463
488
 
464
489
  if (!m_CompositionEventHandler) {
465
490
  // Create CompositionEventHandler if not already created
466
491
  m_context = winrt::Microsoft::ReactNative::ReactContext(context);
467
- m_CompositionEventHandler =
468
- std::make_shared<::Microsoft::ReactNative::CompositionEventHandler>(m_context, *this, componentView.Tag());
492
+ m_CompositionEventHandler = std::make_shared<::Microsoft::ReactNative::CompositionEventHandler>(m_context, *this);
469
493
  m_CompositionEventHandler->Initialize();
470
494
  m_isInitialized = true;
471
495
  }
@@ -538,6 +562,7 @@ void ReactNativeIsland::ClearLoadingUI() noexcept {
538
562
  void ReactNativeIsland::EnsureLoadingUI() noexcept {}
539
563
 
540
564
  void ReactNativeIsland::ShowInstanceLoaded() noexcept {
565
+ VerifyElseCrash(!m_isFragment);
541
566
  if (m_rootVisual) {
542
567
  ClearLoadingUI();
543
568
 
@@ -733,6 +758,9 @@ void ReactNativeIsland::InitTextScaleMultiplier() noexcept {
733
758
  winrt::Windows::Foundation::Size ReactNativeIsland::Measure(
734
759
  const winrt::Microsoft::ReactNative::LayoutConstraints &layoutConstraints,
735
760
  const winrt::Windows::Foundation::Point &viewportOffset) const {
761
+ if (m_isFragment)
762
+ winrt::throw_hresult(E_ILLEGAL_METHOD_CALL);
763
+
736
764
  facebook::react::Size size{0, 0};
737
765
 
738
766
  if (layoutConstraints.LayoutDirection != winrt::Microsoft::ReactNative::LayoutDirection::LeftToRight &&
@@ -774,7 +802,7 @@ void ReactNativeIsland::Arrange(
774
802
  facebook::react::LayoutConstraints fbLayoutConstraints;
775
803
  ApplyConstraints(layoutConstraints, fbLayoutConstraints);
776
804
 
777
- if (m_isInitialized && m_rootTag != -1) {
805
+ if (m_isInitialized && m_rootTag != -1 && !m_isFragment) {
778
806
  if (auto fabricuiManager = ::Microsoft::ReactNative::FabricUIManager::FromProperties(
779
807
  winrt::Microsoft::ReactNative::ReactPropertyBag(m_context.Properties()))) {
780
808
  facebook::react::LayoutContext context;
@@ -813,6 +841,23 @@ winrt::Microsoft::UI::Content::ContentIsland ReactNativeIsland::Island() {
813
841
  rootVisual));
814
842
  m_island = winrt::Microsoft::UI::Content::ContentIsland::Create(rootVisual);
815
843
 
844
+ auto focusController = winrt::Microsoft::UI::Input::InputFocusController::GetForIsland(m_island);
845
+ focusController.NavigateFocusRequested(
846
+ [weakThis = get_weak()](
847
+ const auto &sender, const winrt::Microsoft::UI::Input::FocusNavigationRequestEventArgs &args) {
848
+ if (auto pThis = weakThis.get()) {
849
+ if (auto rootView = pThis->GetComponentView()) {
850
+ args.Result(
851
+ rootView->NavigateFocus(winrt::Microsoft::ReactNative::FocusNavigationRequest(
852
+ winrt::Microsoft::ReactNative::FocusNavigationReason::First))
853
+ ? winrt::Microsoft::UI::Input::FocusNavigationResult::Moved
854
+ : winrt::Microsoft::UI::Input::FocusNavigationResult::NotMoved);
855
+ } else {
856
+ args.Result(winrt::Microsoft::UI::Input::FocusNavigationResult::NoFocusableElements);
857
+ }
858
+ }
859
+ });
860
+
816
861
  // ContentIsland does not support weak_ref, so we cannot use auto_revoke for these events
817
862
  m_islandAutomationProviderRequestedToken = m_island.AutomationProviderRequested(
818
863
  [weakThis = get_weak()](
@@ -896,13 +941,29 @@ void ReactNativeIsland::OnUnmounted() noexcept {
896
941
  if (!m_mounted)
897
942
  return;
898
943
  m_mounted = false;
944
+
945
+ if (m_island && m_island.IsConnected()) {
946
+ auto focusController = winrt::Microsoft::UI::Input::InputFocusController::GetForIsland(m_island);
947
+ auto request = winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(
948
+ winrt::Microsoft::UI::Input::FocusNavigationReason::Programmatic);
949
+ if (focusController.HasFocus()) {
950
+ focusController.DepartFocus(request);
951
+ }
952
+ }
953
+
899
954
  if (auto componentView = GetComponentView()) {
900
955
  componentView->onUnmounted();
901
956
  }
902
957
  }
903
958
 
904
- winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView *
959
+ winrt::com_ptr<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>
905
960
  ReactNativeIsland::GetComponentView() noexcept {
961
+ if (auto portal = m_portal.get()) {
962
+ return winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::PortalComponentView>(portal)
963
+ ->ContentRoot()
964
+ .as<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>();
965
+ }
966
+
906
967
  if (!m_context || m_context.Handle().LoadingState() != winrt::Microsoft::ReactNative::LoadingState::Loaded ||
907
968
  m_rootTag == -1)
908
969
  return nullptr;
@@ -912,8 +973,7 @@ ReactNativeIsland::GetComponentView() noexcept {
912
973
  auto rootComponentViewDescriptor = fabricuiManager->GetViewRegistry().componentViewDescriptorWithTag(
913
974
  static_cast<facebook::react::SurfaceId>(m_rootTag));
914
975
  return rootComponentViewDescriptor.view
915
- .as<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>()
916
- .get();
976
+ .as<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>();
917
977
  }
918
978
  return nullptr;
919
979
  }
@@ -12,6 +12,7 @@
12
12
  #include <winrt/Microsoft.ReactNative.h>
13
13
  #include <winrt/Windows.UI.ViewManagement.h>
14
14
  #include "CompositionEventHandler.h"
15
+ #include "PortalComponentView.h"
15
16
  #include "ReactHost/React.h"
16
17
 
17
18
  namespace winrt::Microsoft::ReactNative::implementation {
@@ -48,15 +49,15 @@ struct ReactNativeIsland
48
49
  ~ReactNativeIsland() noexcept;
49
50
 
50
51
  ReactNativeIsland(const winrt::Microsoft::UI::Composition::Compositor &compositor) noexcept;
51
- ReactNativeIsland(
52
- const winrt::Microsoft::UI::Composition::Compositor &compositor,
53
- winrt::Microsoft::ReactNative::IReactContext context,
54
- winrt::Microsoft::ReactNative::ComponentView componentView) noexcept;
52
+ ReactNativeIsland(const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portal) noexcept;
53
+
54
+ static winrt::Microsoft::ReactNative::ReactNativeIsland CreatePortal(
55
+ const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portal) noexcept;
55
56
  winrt::Microsoft::UI::Content::ContentIsland Island();
56
57
 
57
58
  // property ReactViewHost
58
59
  ReactNative::IReactViewHost ReactViewHost() noexcept;
59
- void ReactViewHost(ReactNative::IReactViewHost const &value) noexcept;
60
+ void ReactViewHost(ReactNative::IReactViewHost const &value);
60
61
 
61
62
  winrt::Microsoft::UI::Composition::Visual RootVisual() noexcept;
62
63
 
@@ -104,7 +105,8 @@ struct ReactNativeIsland
104
105
  winrt::Microsoft::ReactNative::FocusNavigationResult NavigateFocus(
105
106
  const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept;
106
107
 
107
- winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView *GetComponentView() noexcept;
108
+ winrt::com_ptr<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>
109
+ GetComponentView() noexcept;
108
110
 
109
111
  int64_t RootTag() const noexcept;
110
112
 
@@ -153,8 +155,12 @@ struct ReactNativeIsland
153
155
  bool m_hasRenderedVisual{false};
154
156
  bool m_showingLoadingUI{false};
155
157
  bool m_mounted{false};
158
+ winrt::weak_ref<winrt::Microsoft::ReactNative::Composition::PortalComponentView> m_portal{nullptr};
156
159
  IReactDispatcher m_uiDispatcher{nullptr};
157
160
  winrt::IInspectable m_uiaProvider{nullptr};
161
+
162
+ // This is the surfaceId that this island belongs to.
163
+ // In the case of portal content root, this will be the surfaceId that contains the portal.
158
164
  int64_t m_rootTag{-1};
159
165
  float m_scaleFactor{1.0};
160
166
  float m_textScaleMultiplier{1.0};
@@ -17,7 +17,8 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
17
17
  RootComponentView::RootComponentView(
18
18
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
19
19
  facebook::react::Tag tag,
20
- winrt::Microsoft::ReactNative::ReactContext const &reactContext)
20
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext,
21
+ ReactCompositionViewComponentBuilder *builder)
21
22
  : base_type(
22
23
  {}, // default viewProps
23
24
  compContext,
@@ -25,20 +26,34 @@ RootComponentView::RootComponentView(
25
26
  reactContext,
26
27
  ComponentViewFeatures::Default &
27
28
  ~(ComponentViewFeatures::Background | ComponentViewFeatures::ShadowProps |
28
- ComponentViewFeatures::NativeBorder | ComponentViewFeatures::FocusVisual)) {}
29
+ ComponentViewFeatures::NativeBorder | ComponentViewFeatures::FocusVisual),
30
+ builder) {}
31
+
32
+ RootComponentView::RootComponentView(
33
+ const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
34
+ const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portal,
35
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext)
36
+ : base_type(
37
+ {}, // default viewProps
38
+ compContext,
39
+ -1,
40
+ reactContext,
41
+ ComponentViewFeatures::Default &
42
+ ~(ComponentViewFeatures::Background | ComponentViewFeatures::ShadowProps |
43
+ ComponentViewFeatures::NativeBorder | ComponentViewFeatures::FocusVisual),
44
+ nullptr // builder,
45
+ ),
46
+ m_wkPortal(portal) {}
29
47
 
30
48
  RootComponentView::~RootComponentView() {
31
- if (auto rootView = m_wkRootView.get()) {
32
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->RemoveRenderedVisual(
33
- OuterVisual());
34
- }
49
+ stop();
35
50
  }
36
51
 
37
52
  winrt::Microsoft::ReactNative::ComponentView RootComponentView::Create(
38
53
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
39
54
  facebook::react::Tag tag,
40
55
  winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept {
41
- return winrt::make<RootComponentView>(compContext, tag, reactContext);
56
+ return winrt::make<RootComponentView>(compContext, tag, reactContext, nullptr);
42
57
  }
43
58
 
44
59
  RootComponentView *RootComponentView::rootComponentView() const noexcept {
@@ -84,13 +99,13 @@ void RootComponentView::SetFocusedComponent(const winrt::Microsoft::ReactNative:
84
99
 
85
100
  bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept {
86
101
  if (request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::Restore) {
87
- // No-op for now
88
- return m_focusedComponent != nullptr;
102
+ if (m_focusedComponent)
103
+ return true;
89
104
  }
90
105
 
91
- auto view = (request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::First)
92
- ? FocusManager::FindFirstFocusableElement(*this)
93
- : FocusManager::FindLastFocusableElement(*this);
106
+ auto view = (request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::Last)
107
+ ? FocusManager::FindLastFocusableElement(*this)
108
+ : FocusManager::FindFirstFocusableElement(*this);
94
109
  if (view) {
95
110
  TrySetFocusedComponent(
96
111
  view,
@@ -116,8 +131,10 @@ bool RootComponentView::TrySetFocusedComponent(
116
131
  selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
117
132
  }
118
133
 
119
- if (selfView && selfView->rootComponentView() != this)
134
+ if (selfView && selfView->rootComponentView() != this) {
135
+ assert(false);
120
136
  return false;
137
+ }
121
138
 
122
139
  auto losingFocusArgs = winrt::make<winrt::Microsoft::ReactNative::implementation::LosingFocusEventArgs>(
123
140
  target, direction, m_focusedComponent, target);
@@ -197,7 +214,7 @@ HRESULT RootComponentView::GetFragmentRoot(IRawElementProviderFragmentRoot **pRe
197
214
  if (uiManager == nullptr)
198
215
  return UIA_E_ELEMENTNOTAVAILABLE;
199
216
 
200
- auto rootView{uiManager->GetReactNativeIsland(Tag())};
217
+ auto rootView = m_wkRootView.get();
201
218
  if (!rootView) {
202
219
  return UIA_E_ELEMENTNOTAVAILABLE;
203
220
  }
@@ -214,10 +231,43 @@ uint32_t RootComponentView::overlayIndex() noexcept {
214
231
  return 1;
215
232
  }
216
233
 
217
- void RootComponentView::start(const winrt::Microsoft::ReactNative::ReactNativeIsland &rootView) noexcept {
218
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->AddRenderedVisual(
234
+ void RootComponentView::start(const winrt::Microsoft::ReactNative::ReactNativeIsland &island) noexcept {
235
+ theme(winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::Theme>(island.Theme()));
236
+
237
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(island)->AddRenderedVisual(
219
238
  OuterVisual());
220
- m_wkRootView = rootView;
239
+ m_visualAddedToIsland = true;
240
+ ReactNativeIsland(island);
241
+ }
242
+
243
+ void RootComponentView::stop() noexcept {
244
+ SetFocusedComponent(nullptr);
245
+ if (m_visualAddedToIsland) {
246
+ if (auto rootView = m_wkRootView.get()) {
247
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->RemoveRenderedVisual(
248
+ OuterVisual());
249
+ }
250
+ m_visualAddedToIsland = false;
251
+ }
252
+ // Disconnect from the Island. In case of an instance reload, the island may now
253
+ // be attached to a new RootComponentView, so we should stop interacting with it.
254
+ ReactNativeIsland(nullptr);
255
+ }
256
+
257
+ void RootComponentView::ReactNativeIsland(const winrt::Microsoft::ReactNative::ReactNativeIsland &island) noexcept {
258
+ m_wkRootView = island;
259
+ }
260
+
261
+ winrt::Microsoft::ReactNative::ReactNativeIsland RootComponentView::ReactNativeIsland() noexcept {
262
+ return m_wkRootView.get();
263
+ }
264
+
265
+ winrt::Microsoft::ReactNative::Composition::PortalComponentView RootComponentView::Portal() const noexcept {
266
+ return m_wkPortal.get();
267
+ }
268
+
269
+ facebook::react::Point RootComponentView::getClientOffset() const noexcept {
270
+ return {};
221
271
  }
222
272
 
223
273
  winrt::IInspectable RootComponentView::UiaProviderFromPoint(const POINT &ptPixels) noexcept {
@@ -226,6 +276,10 @@ winrt::IInspectable RootComponentView::UiaProviderFromPoint(const POINT &ptPixel
226
276
  static_cast<facebook::react::Float>(ptPixels.y) / m_layoutMetrics.pointScaleFactor};
227
277
 
228
278
  facebook::react::Point localPt;
279
+
280
+ // In the case of a sub rootview, we may have a non-zero origin. hitTest takes a pt in the parent coords, so we need
281
+ // to apply the current origin
282
+ ptDips += m_layoutMetrics.frame.origin;
229
283
  auto tag = hitTest(ptDips, localPt, true);
230
284
 
231
285
  auto uiManager = ::Microsoft::ReactNative::FabricUIManager::FromProperties(m_reactContext.Properties());
@@ -46,6 +46,12 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
46
46
  // Index that visuals can be inserted into OuterVisual for debugging UI
47
47
  uint32_t overlayIndex() noexcept;
48
48
  void start(const winrt::Microsoft::ReactNative::ReactNativeIsland &rootView) noexcept;
49
+ void stop() noexcept;
50
+
51
+ void ReactNativeIsland(const winrt::Microsoft::ReactNative::ReactNativeIsland &rootView) noexcept;
52
+ winrt::Microsoft::ReactNative::ReactNativeIsland ReactNativeIsland() noexcept;
53
+
54
+ facebook::react::Point getClientOffset() const noexcept override;
49
55
 
50
56
  HRESULT GetFragmentRoot(IRawElementProviderFragmentRoot **pRetVal) noexcept;
51
57
  winrt::Microsoft::ReactNative::implementation::ClipState getClipState() noexcept override;
@@ -60,8 +66,16 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
60
66
  RootComponentView(
61
67
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
62
68
  facebook::react::Tag tag,
69
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext,
70
+ ReactCompositionViewComponentBuilder *builder);
71
+
72
+ RootComponentView(
73
+ const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
74
+ const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portal,
63
75
  winrt::Microsoft::ReactNative::ReactContext const &reactContext);
64
76
 
77
+ winrt::Microsoft::ReactNative::Composition::PortalComponentView Portal() const noexcept;
78
+
65
79
  virtual ~RootComponentView();
66
80
 
67
81
  winrt::Microsoft::ReactNative::ComponentView FindFirstFocusableElement() noexcept;
@@ -75,6 +89,8 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
75
89
  // happening.
76
90
  winrt::Microsoft::ReactNative::ComponentView m_focusedComponent{nullptr};
77
91
  winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> m_wkRootView{nullptr};
92
+ winrt::weak_ref<winrt::Microsoft::ReactNative::Composition::PortalComponentView> m_wkPortal{nullptr};
93
+ bool m_visualAddedToIsland{false};
78
94
  };
79
95
 
80
96
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -1221,7 +1221,7 @@ void WindowsTextInputComponentView::onMounted() noexcept {
1221
1221
  InternalFinalize();
1222
1222
  }
1223
1223
 
1224
- std::optional<std::string> WindowsTextInputComponentView::getAcccessiblityValue() noexcept {
1224
+ std::optional<std::string> WindowsTextInputComponentView::getAccessiblityValue() noexcept {
1225
1225
  return GetTextFromRichEdit();
1226
1226
  }
1227
1227
 
@@ -67,7 +67,7 @@ struct WindowsTextInputComponentView
67
67
  &args) noexcept override;
68
68
  void onMounted() noexcept override;
69
69
 
70
- std::optional<std::string> getAcccessiblityValue() noexcept override;
70
+ std::optional<std::string> getAccessiblityValue() noexcept override;
71
71
  void setAcccessiblityValue(std::string &&value) noexcept override;
72
72
  bool getAcccessiblityIsReadOnly() noexcept override;
73
73