react-native-windows 0.76.8 → 0.76.9

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 (128) 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 +229 -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 +8 -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 +3 -0
  11. package/Libraries/Components/View/ViewPropTypes.windows.js +3 -0
  12. package/Libraries/Image/Image.windows.js +7 -0
  13. package/Libraries/Modal/Modal.windows.js +4 -1
  14. package/Libraries/Text/Text.windows.js +14 -1
  15. package/Libraries/Text/TextProps.windows.js +3 -0
  16. package/Microsoft.ReactNative/CompositionComponentView.idl +13 -1
  17. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.cpp +97 -0
  18. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.h +53 -0
  19. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +160 -17
  20. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
  21. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -2
  22. package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +0 -5
  23. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +428 -39
  24. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +39 -1
  25. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +55 -33
  26. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +5 -3
  27. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +43 -5
  28. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +2 -1
  29. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +115 -0
  30. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +41 -0
  31. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +298 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +59 -0
  33. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +106 -56
  34. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
  35. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +163 -10
  36. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +17 -1
  37. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +4 -2
  38. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +9 -1
  39. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +348 -316
  40. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +3 -61
  41. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +78 -0
  42. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.h +52 -0
  43. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +22 -0
  44. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +7 -5
  45. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +99 -37
  46. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -6
  47. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +81 -22
  48. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +21 -2
  49. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +6 -1
  50. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +41 -37
  51. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +76 -33
  52. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +8 -2
  53. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +1 -6
  54. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +0 -3
  55. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +0 -2
  56. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +5 -8
  57. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +1 -2
  58. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorUtils.cpp +1 -1
  59. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +15 -1
  60. package/Microsoft.ReactNative/IReactContext.cpp +2 -2
  61. package/Microsoft.ReactNative/IReactContext.h +1 -1
  62. package/Microsoft.ReactNative/IReactContext.idl +2 -2
  63. package/Microsoft.ReactNative/IReactPackageBuilder.idl +3 -3
  64. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +97 -87
  65. package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +4 -0
  66. package/Microsoft.ReactNative/Modules/AlertModule.cpp +9 -4
  67. package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedNodeManager.cpp +1 -1
  68. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.cpp +32 -35
  69. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.h +7 -4
  70. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +1 -1
  71. package/Microsoft.ReactNative/Modules/AppThemeModuleUwp.cpp +2 -2
  72. package/Microsoft.ReactNative/Modules/AppearanceModule.cpp +2 -2
  73. package/Microsoft.ReactNative/Modules/ClipboardModule.cpp +1 -1
  74. package/Microsoft.ReactNative/Modules/ClipboardModule.h +1 -1
  75. package/Microsoft.ReactNative/Modules/DeviceInfoModule.cpp +3 -3
  76. package/Microsoft.ReactNative/Modules/I18nManagerModule.cpp +1 -1
  77. package/Microsoft.ReactNative/Modules/LogBoxModule.cpp +7 -5
  78. package/Microsoft.ReactNative/Modules/LogBoxModule.h +2 -1
  79. package/Microsoft.ReactNative/Modules/Timing.cpp +2 -2
  80. package/Microsoft.ReactNative/ReactHost/IReactInstance.h +5 -0
  81. package/Microsoft.ReactNative/ReactHost/React.h +0 -3
  82. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +36 -12
  83. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  84. package/Microsoft.ReactNative/ReactNativeHost.cpp +9 -4
  85. package/Microsoft.ReactNative/ReactNativeIsland.idl +5 -1
  86. package/Microsoft.ReactNative/ReactPackageBuilder.cpp +3 -3
  87. package/Microsoft.ReactNative/ReactPackageBuilder.h +4 -4
  88. package/Microsoft.ReactNative/Utils/Helpers.cpp +0 -2
  89. package/Microsoft.ReactNative/Views/DevMenu.cpp +6 -6
  90. package/Microsoft.ReactNative/Views/DevMenu.h +1 -1
  91. package/Microsoft.ReactNative/XamlUIService.cpp +13 -7
  92. package/Microsoft.ReactNative/XamlUIService.h +4 -1
  93. package/Microsoft.ReactNative/XamlUIService.idl +2 -0
  94. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +6 -2
  95. package/Microsoft.ReactNative.Cxx/NativeModules.h +29 -0
  96. package/Microsoft.ReactNative.Cxx/ReactContext.h +1 -1
  97. package/Microsoft.ReactNative.Cxx/XamlUtils.h +12 -0
  98. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  99. package/PropertySheets/React.Cpp.props +3 -0
  100. package/PropertySheets/WebView2.props +1 -1
  101. package/PropertySheets/WinUI.props +5 -4
  102. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h +253 -0
  103. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h +799 -0
  104. package/Shared/InspectorPackagerConnection.cpp +2 -5
  105. package/Shared/InspectorPackagerConnection.h +2 -2
  106. package/Shared/Networking/WinRTWebSocketResource.cpp +369 -7
  107. package/Shared/Networking/WinRTWebSocketResource.h +118 -0
  108. package/Shared/Shared.vcxitems +12 -5
  109. package/Shared/Shared.vcxitems.filters +11 -4
  110. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +212 -0
  111. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +295 -0
  112. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +200 -0
  113. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +224 -0
  114. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +250 -0
  115. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +267 -0
  116. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +234 -0
  117. package/codegen/react/components/rnwcore/InputAccessory.g.h +200 -0
  118. package/codegen/react/components/rnwcore/ModalHostView.g.h +279 -0
  119. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +246 -0
  120. package/codegen/react/components/rnwcore/SafeAreaView.g.h +197 -0
  121. package/codegen/react/components/rnwcore/Switch.g.h +263 -0
  122. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +200 -0
  123. package/just-task.js +1 -1
  124. package/package.json +3 -3
  125. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +0 -191
  126. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentDescriptor.h +0 -39
  127. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.cpp +0 -18
  128. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.h +0 -39
@@ -5,379 +5,411 @@
5
5
 
6
6
  #include "WindowsModalHostViewComponentView.h"
7
7
 
8
- #include <AutoDraw.h>
9
- #include <Fabric/DWriteHelpers.h>
10
- #include "../CompositionDynamicAutomationProvider.h"
11
- #include "Unicode.h"
12
-
13
- #include <DispatcherQueue.h>
14
- #include <Fabric/ComponentView.h>
15
- #include <Fabric/Composition/CompositionContextHelper.h>
16
- #include <Fabric/Composition/CompositionUIService.h>
17
- #include <Fabric/Composition/ReactNativeIsland.h>
18
- #include <windows.ui.composition.interop.h>
19
- #include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
8
+ #include "../../../codegen/react/components/rnwcore/ModalHostView.g.h"
9
+ #include <ComponentView.Experimental.interop.h>
20
10
  #include <winrt/Microsoft.UI.Content.h>
11
+ #include <winrt/Microsoft.UI.Input.h>
12
+ #include <winrt/Microsoft.UI.Windowing.h>
21
13
  #include <winrt/Microsoft.UI.interop.h>
22
- #include <winrt/Windows.UI.Composition.Desktop.h>
23
- #include <winrt/Windows.UI.Composition.h>
24
- #include "IReactContext.h"
25
- #include "ReactHost/ReactInstanceWin.h"
26
- #include "ReactNativeHost.h"
27
- #include "WindowsModalHostViewShadowNode.h"
28
14
 
29
15
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
30
- WindowsModalHostComponentView::WindowsModalHostComponentView(
31
- const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
32
- facebook::react::Tag tag,
33
- winrt::Microsoft::ReactNative::ReactContext const &reactContext)
34
- : Super(compContext, tag, reactContext) {}
35
-
36
- WindowsModalHostComponentView::~WindowsModalHostComponentView() {
37
- // dispatch onDismiss event
38
- auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
39
- facebook::react::ModalHostViewEventEmitter::OnDismiss onDismissArgs;
40
- emitter->onDismiss(onDismissArgs);
41
-
42
- // reset the topWindowID
43
- if (m_prevWindowID) {
44
- auto host =
45
- winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
46
- winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
47
- host.InstanceSettings().Properties(), m_prevWindowID);
48
- m_prevWindowID = 0;
49
- }
50
16
 
51
- // enable input to parent
52
- EnableWindow(m_parentHwnd, true);
17
+ struct ModalHostState
18
+ : winrt::implements<ModalHostState, winrt::Microsoft::ReactNative::Composition::IPortalStateData> {
19
+ ModalHostState(winrt::Microsoft::ReactNative::LayoutConstraints layoutConstraints, float scaleFactor)
20
+ : m_layoutConstraints(layoutConstraints), m_pointScaleFactor(scaleFactor) {}
53
21
 
54
- // Check if the window handle (m_hwnd) exists and destroy it if necessary
55
- if (m_hwnd) {
56
- // Close/Destroy the modal window
57
- SendMessage(m_hwnd, WM_DESTROY, 0, 0);
58
- m_hwnd = nullptr;
22
+ winrt::Microsoft::ReactNative::LayoutConstraints LayoutConstraints() const noexcept {
23
+ return m_layoutConstraints;
59
24
  }
60
- }
61
-
62
- winrt::Microsoft::ReactNative::ComponentView WindowsModalHostComponentView::Create(
63
- const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
64
- facebook::react::Tag tag,
65
- winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept {
66
- return winrt::make<WindowsModalHostComponentView>(compContext, tag, reactContext);
67
- }
68
-
69
- // constants for creating a new windows
70
- constexpr PCWSTR c_modalWindowClassName = L"MS_REACTNATIVE_MODAL";
71
- constexpr auto CompHostProperty = L"CompHost";
72
- const int MODAL_MIN_WIDTH = 50;
73
- const int MODAL_MIN_HEIGHT = 50;
74
-
75
- float ScaleFactor(HWND hwnd) noexcept {
76
- return GetDpiForWindow(hwnd) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
77
- }
78
25
 
79
- // creates a new modal window
80
- void WindowsModalHostComponentView::EnsureModalCreated() {
81
- auto host =
82
- winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
83
-
84
- // return if hwnd already exists
85
- if (!host || m_hwnd) {
86
- return;
26
+ float PointScaleFactor() const noexcept {
27
+ return m_pointScaleFactor;
87
28
  }
88
29
 
89
- RegisterWndClass();
90
-
91
- HINSTANCE hInstance = GetModuleHandle(NULL);
92
- winrt::com_ptr<::IUnknown> spunk;
30
+ private:
31
+ float m_pointScaleFactor{1.0f};
32
+ winrt::Microsoft::ReactNative::LayoutConstraints m_layoutConstraints;
33
+ };
93
34
 
94
- // get the root hwnd
95
- m_prevWindowID =
96
- winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(m_reactContext.Properties().Handle());
35
+ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::Foundation::IInspectable>,
36
+ ::Microsoft::ReactNativeSpecs::BaseModalHostView<ModalHostView> {
37
+ ~ModalHostView() {
38
+ if (m_window && m_window.IsVisible()) {
39
+ CloseWindow();
40
+ }
97
41
 
98
- m_parentHwnd = GetHwndForParenting();
42
+ if (m_reactNativeIsland) {
43
+ m_reactNativeIsland.Island().Close();
44
+ }
99
45
 
100
- auto windowsStyle = m_showTitleBar ? WS_OVERLAPPEDWINDOW : WS_POPUP;
46
+ if (m_bridge) {
47
+ if (m_departFocusToken && !m_bridge.IsClosed()) {
48
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(m_bridge);
49
+ navHost.DepartFocusRequested(m_departFocusToken);
50
+ }
51
+ m_bridge.Close();
52
+ }
101
53
 
102
- m_hwnd = CreateWindow(
103
- c_modalWindowClassName,
104
- L"React-Native Modal",
105
- windowsStyle,
106
- CW_USEDEFAULT,
107
- CW_USEDEFAULT,
108
- MODAL_MIN_WIDTH,
109
- MODAL_MIN_HEIGHT,
110
- m_parentHwnd, // parent
111
- nullptr,
112
- hInstance,
113
- spunk.get());
54
+ if (m_window) {
55
+ m_window.Destroy();
56
+ m_window = nullptr;
57
+ }
114
58
 
115
- // Check if window creation succeeded
116
- if (!m_hwnd) {
117
- throw std::exception("Failed to create new hwnd for Modal: " + GetLastError());
59
+ #ifdef USE_EXPERIMENTAL_WINUI3
60
+ if (m_popUp) {
61
+ m_popUp.Close();
62
+ m_popUp = nullptr;
63
+ }
64
+ #endif
118
65
  }
119
66
 
120
- // Disable user sizing of the hwnd
121
- ::SetWindowLong(m_hwnd, GWL_STYLE, GetWindowLong(m_hwnd, GWL_STYLE) & ~WS_SIZEBOX);
122
-
123
- // set the top-level windows as the new hwnd
124
- winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
125
- host.InstanceSettings().Properties(), reinterpret_cast<uint64_t>(m_hwnd));
126
-
127
- // get current compositor - handles the creation/manipulation of visual objects
128
- auto compositionContext = CompositionContext();
129
- auto compositor =
130
- winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::InnerCompositor(
131
- compositionContext);
132
-
133
- // create a react native island - code taken from CompositionHwndHost
134
- auto bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
135
- compositor, winrt::Microsoft::UI::GetWindowIdFromWindow(m_hwnd));
136
- m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland(compositor, m_reactContext.Handle(), *this);
137
- auto contentIsland = m_reactNativeIsland.Island();
138
- bridge.Connect(contentIsland);
139
- bridge.Show();
140
-
141
- // set ScaleFactor
142
- ScaleFactor(m_hwnd);
143
-
144
- // set layout contraints
145
- winrt::Microsoft::ReactNative::LayoutConstraints constraints;
146
- constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
147
-
148
- RECT rc;
149
- GetClientRect(m_parentHwnd, &rc);
150
- // Maximum size is set to size of parent hwnd
151
- constraints.MaximumSize = {(rc.right - rc.left) * ScaleFactor(m_hwnd), (rc.bottom - rc.top) / ScaleFactor(m_hwnd)};
152
- constraints.MinimumSize = {MODAL_MIN_WIDTH * ScaleFactor(m_hwnd), MODAL_MIN_HEIGHT * ScaleFactor(m_hwnd)};
153
- m_reactNativeIsland.Arrange(constraints, {0, 0});
154
- bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
155
-
156
- spunk.detach();
157
- }
158
-
159
- void WindowsModalHostComponentView::ShowOnUIThread() {
160
- if (m_hwnd && !IsWindowVisible(m_hwnd)) {
161
- ShowWindow(m_hwnd, SW_NORMAL);
162
- BringWindowToTop(m_hwnd);
163
- SetFocus(m_hwnd);
67
+ void InitializePortalViewComponent(
68
+ const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portalComponentView) noexcept {
69
+ m_reactContext = portalComponentView.ReactContext();
164
70
 
165
- // disable input to parent
166
- EnableWindow(m_parentHwnd, false);
71
+ portalComponentView.Mounted(
72
+ [](const auto & /*sender*/, const auto &view) { view.UserData().as<ModalHostView>()->OnMounted(view); });
73
+ portalComponentView.Unmounted(
74
+ [](const auto & /*sender*/, const auto &view) { view.UserData().as<ModalHostView>()->OnUnmounted(view); });
75
+ }
167
76
 
168
- // dispatch onShow event
169
- auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
170
- facebook::react::ModalHostViewEventEmitter::OnShow onShowArgs;
171
- emitter->onShow(onShowArgs);
77
+ void UpdateProps(
78
+ const winrt::Microsoft::ReactNative::ComponentView &view,
79
+ const winrt::com_ptr<::Microsoft::ReactNativeSpecs::ModalHostViewProps> &newProps,
80
+ const winrt::com_ptr<::Microsoft::ReactNativeSpecs::ModalHostViewProps> &oldProps) noexcept override {
81
+ if (!oldProps || newProps->visible != oldProps->visible) {
82
+ if (newProps->visible.value_or(true)) {
83
+ // We do not immediately show the window, since we want to resize/position
84
+ // the window based on the layout metrics before we show it
85
+ m_showQueued = true;
86
+ } else {
87
+ CloseWindow();
88
+ }
89
+ }
90
+ ::Microsoft::ReactNativeSpecs::BaseModalHostView<ModalHostView>::UpdateProps(view, newProps, oldProps);
172
91
  }
173
- }
174
92
 
175
- void WindowsModalHostComponentView::HideOnUIThread() noexcept {
176
- if (m_hwnd) {
177
- SendMessage(m_hwnd, WM_CLOSE, 0, 0);
93
+ void UpdateState(
94
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
95
+ const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept override {
96
+ m_state = newState;
178
97
  }
179
98
 
180
- // dispatch onDismiss event
181
- auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
182
- facebook::react::ModalHostViewEventEmitter::OnDismiss onDismissArgs;
183
- emitter->onDismiss(onDismissArgs);
99
+ void MountChildComponentView(
100
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
101
+ const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept override {
102
+ AdjustWindowSize(args.Child().LayoutMetrics());
103
+ assert(!m_childLayoutMetricsToken);
104
+ m_childLayoutMetricsToken = args.Child().LayoutMetricsChanged(
105
+ [wkThis = get_weak()](
106
+ auto &sender, const winrt::Microsoft::ReactNative::LayoutMetricsChangedArgs &layoutMetricsChangedArgs) {
107
+ if (auto strongThis = wkThis.get()) {
108
+ strongThis->AdjustWindowSize(layoutMetricsChangedArgs.NewLayoutMetrics());
109
+ }
110
+ });
111
+ }
184
112
 
185
- // enable input to parent
186
- EnableWindow(m_parentHwnd, true);
113
+ void UnmountChildComponentView(
114
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
115
+ const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &args) noexcept override {
116
+ assert(m_childLayoutMetricsToken);
117
+ args.Child().LayoutMetricsChanged(m_childLayoutMetricsToken);
118
+ m_childLayoutMetricsToken.value = 0;
119
+ }
187
120
 
188
- // reset the topWindowID
189
- if (m_prevWindowID) {
190
- auto host =
191
- winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
192
- winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
193
- host.InstanceSettings().Properties(), m_prevWindowID);
194
- m_prevWindowID = 0;
121
+ void FinalizeUpdate(
122
+ const winrt::Microsoft::ReactNative::ComponentView &view,
123
+ winrt::Microsoft::ReactNative::ComponentViewUpdateMask /*mask*/) noexcept override {
124
+ if (m_showQueued) {
125
+ ShowOnUIThread(view);
126
+ }
195
127
  }
196
- }
197
128
 
198
- // Windows Procedure - callback function used for handling all messages (generated by NTUser or manual calls to
199
- // SendMessage)
200
- LRESULT CALLBACK ModalBoxWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept {
201
- auto data = reinterpret_cast<::IUnknown *>(GetProp(
202
- hwnd,
203
- CompHostProperty)); // gets data handle from the property list of specified window (ie the window we want to make)
204
- winrt::Microsoft::ReactNative::CompositionHwndHost host{nullptr};
205
-
206
- if (data) {
207
- winrt::check_hresult(data->QueryInterface(
208
- winrt::guid_of<winrt::Microsoft::ReactNative::CompositionHwndHost>(),
209
- winrt::put_abi(host))); // look into the data for a CompositionHwndHost and store it in host
210
- auto result = static_cast<LRESULT>(host.TranslateMessage(message, wparam, lparam));
211
- if (result) {
212
- return result;
129
+ private:
130
+ void OnMounted(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
131
+ m_mounted = true;
132
+ if (m_showQueued) {
133
+ ShowOnUIThread(view);
213
134
  }
214
135
  }
215
136
 
216
- switch (message) {
217
- case WM_NCCREATE: { // called before WM_CREATE, lparam should be identical to members of CreateWindowEx
218
- auto createStruct = reinterpret_cast<CREATESTRUCT *>(lparam); // CreateStruct
219
- data = static_cast<::IUnknown *>(createStruct->lpCreateParams);
220
- SetProp(hwnd, CompHostProperty, data); // adds new properties to window
221
- break;
137
+ void OnUnmounted(const winrt::Microsoft::ReactNative::ComponentView & /*view*/) noexcept {
138
+ m_mounted = false;
139
+ }
140
+
141
+ void AdjustWindowSize(const winrt::Microsoft::ReactNative::LayoutMetrics &layoutMetrics) noexcept {
142
+ #ifdef USE_EXPERIMENTAL_WINUI3
143
+ if (!m_popUp) {
144
+ #else
145
+ if (!m_window) {
146
+ #endif
147
+ return;
222
148
  }
223
- case WM_CLOSE: {
224
- // Just hide the window instead of destroying it
225
- ::ShowWindow(hwnd, SW_HIDE);
226
- return 0;
149
+
150
+ if (layoutMetrics.Frame.Width == 0 && layoutMetrics.Frame.Height == 0) {
151
+ return;
227
152
  }
228
- case WM_DESTROY: { // called when we want to destroy the window
229
- ::ShowWindow(hwnd, SW_HIDE);
230
- if (data) {
231
- data->Release();
153
+
154
+ // get Modal's position based on parent
155
+ RECT parentRC;
156
+ GetWindowRect(m_parentHwnd, &parentRC);
157
+ int32_t xCor = static_cast<int32_t>(
158
+ (parentRC.left + parentRC.right - layoutMetrics.Frame.Width * layoutMetrics.PointScaleFactor) / 2);
159
+ int32_t yCor = static_cast<int32_t>(
160
+ (parentRC.top + parentRC.bottom - layoutMetrics.Frame.Height * layoutMetrics.PointScaleFactor) / 2);
161
+
162
+ #ifdef USE_EXPERIMENTAL_WINUI3
163
+ winrt::Windows::Graphics::RectInt32 rect2{
164
+ (int)xCor,
165
+ (int)yCor,
166
+ static_cast<int32_t>(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)),
167
+ static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor))};
168
+ m_popUp.MoveAndResize(rect2);
169
+ #else
170
+ // Fix for https://github.com/microsoft/microsoft-ui-xaml/issues/9529
171
+ auto titleBarHeight = m_window.TitleBar().Height();
172
+
173
+ // Adjust window position and size
174
+ m_window.ResizeClient(
175
+ {static_cast<int32_t>(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)),
176
+ static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor)) - titleBarHeight});
177
+ m_window.Move({xCor, yCor});
178
+ #endif
179
+ };
180
+
181
+ void ShowOnUIThread(const winrt::Microsoft::ReactNative::ComponentView &view) {
182
+ if (!m_mounted)
183
+ return;
184
+
185
+ m_showQueued = false;
186
+ EnsureModalCreated(view);
187
+
188
+ #ifdef USE_EXPERIMENTAL_WINUI3
189
+ if (m_popUp) {
190
+ m_bridge.Enable();
191
+ m_popUp.Show();
192
+
193
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(
194
+ m_popUp.as<winrt::Microsoft::UI::Content::IContentSiteBridge>());
195
+ auto result = navHost.NavigateFocus(winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(
196
+ winrt::Microsoft::UI::Input::FocusNavigationReason::First));
197
+
198
+ // dispatch onShow event
199
+ if (auto eventEmitter = EventEmitter()) {
200
+ ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnShow eventArgs;
201
+ eventEmitter->onShow(eventArgs);
232
202
  }
233
- SetProp(hwnd, CompHostProperty, nullptr);
234
- break;
235
203
  }
236
- }
204
+ #endif
237
205
 
238
- return DefWindowProc(hwnd, message, wparam, lparam);
239
- }
206
+ if (m_window && !m_window.IsVisible()) {
207
+ m_bridge.Enable();
208
+ m_window.Show(true);
209
+
210
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(m_bridge);
211
+ auto result = navHost.NavigateFocus(winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(
212
+ winrt::Microsoft::UI::Input::FocusNavigationReason::First));
240
213
 
241
- // Creates and Register a new window class
242
- void WindowsModalHostComponentView::RegisterWndClass() noexcept {
243
- static bool registered = false;
244
- if (registered) {
245
- return;
214
+ // dispatch onShow event
215
+ if (auto eventEmitter = EventEmitter()) {
216
+ ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnShow eventArgs;
217
+ eventEmitter->onShow(eventArgs);
218
+ }
219
+ }
246
220
  }
247
221
 
248
- HINSTANCE hInstance =
249
- GetModuleHandle(NULL); // returns a handle to the file used to create the calling process (.exe file)
250
-
251
- WNDCLASSEX wcex = {}; // contains window class information
252
- wcex.cbSize = sizeof(wcex); // size of windows class (bytes)
253
- wcex.style = CS_HREDRAW | CS_VREDRAW; // class style (redraw window on size adjustment)
254
- wcex.lpfnWndProc = &ModalBoxWndProc; // pointer to windows procedure
255
- wcex.cbClsExtra = DLGWINDOWEXTRA; // extra bytes to allocate
256
- wcex.cbWndExtra =
257
- sizeof(winrt::impl::abi<winrt::Microsoft::ReactNative::ICompositionHwndHost>::type *); // extra bytes to allocate
258
- wcex.hInstance = hInstance;
259
- wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // handle to class cursor
260
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // background color
261
- wcex.lpszClassName = c_modalWindowClassName; // specify resource name
262
- ATOM classId = RegisterClassEx(&wcex); // register new windows class
263
- WINRT_VERIFY(classId); // 0 = fail
264
- winrt::check_win32(!classId);
265
-
266
- registered = true;
267
- }
222
+ void CloseWindow() noexcept {
223
+ // enable input to parent before closing the modal window, so focus can return back to the parent window
224
+ EnableWindow(m_parentHwnd, true);
268
225
 
269
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual
270
- WindowsModalHostComponentView::VisualToMountChildrenInto() noexcept {
271
- return m_reactNativeIsland
272
- .as<winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
273
- .InternalRootVisual();
274
- }
226
+ if (m_window) {
227
+ m_window.Hide();
228
+ }
275
229
 
276
- // childComponentView - reference to the child component view
277
- // index - the position in which the childComponentView should be mounted
278
- void WindowsModalHostComponentView::MountChildComponentView(
279
- const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
280
- uint32_t index) noexcept {
281
- EnsureModalCreated();
282
- base_type::MountChildComponentView(childComponentView, index);
283
- }
230
+ #ifdef USE_EXPERIMENTAL_WINUI3
231
+ if (m_popUp) {
232
+ m_popUp.Hide();
233
+ }
234
+ #endif
284
235
 
285
- void WindowsModalHostComponentView::UnmountChildComponentView(
286
- const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
287
- uint32_t index) noexcept {
288
- base_type::UnmountChildComponentView(childComponentView, index);
289
- }
236
+ // dispatch onDismiss event
237
+ if (auto eventEmitter = EventEmitter()) {
238
+ ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnDismiss eventArgs;
239
+ eventEmitter->onDismiss(eventArgs);
240
+ }
290
241
 
291
- void WindowsModalHostComponentView::updateLayoutMetrics(
292
- facebook::react::LayoutMetrics const &layoutMetrics,
293
- facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
294
- base_type::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
295
- if (m_hwnd) {
296
- EnsureModalCreated();
297
- AdjustWindowSize();
298
- ShowOnUIThread();
299
- }
300
- }
242
+ // reset the topWindowID
243
+ if (m_prevWindowID) {
244
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
245
+ m_reactContext.Properties().Handle(), m_prevWindowID);
246
+ m_prevWindowID = 0;
247
+ }
301
248
 
302
- void WindowsModalHostComponentView::AdjustWindowSize() noexcept {
303
- if (m_layoutMetrics.overflowInset.right == 0 && m_layoutMetrics.overflowInset.bottom == 0) {
304
- return;
249
+ m_bridge.Disable();
305
250
  }
306
251
 
307
- // Modal's size is based on it's children, use the overflow to calculate the width/height
308
- float xPos = (-m_layoutMetrics.overflowInset.right * (m_layoutMetrics.pointScaleFactor));
309
- float yPos = (-m_layoutMetrics.overflowInset.bottom * (m_layoutMetrics.pointScaleFactor));
310
- RECT rc;
311
- GetClientRect(m_hwnd, &rc);
312
- RECT rect = {0, 0, (int)xPos, (int)yPos};
252
+ // creates a new modal window
253
+ void EnsureModalCreated(const winrt::Microsoft::ReactNative::ComponentView &view) {
254
+ if (m_window) {
255
+ return;
256
+ }
313
257
 
314
- if (m_showTitleBar) {
315
- AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); // Adjust for title bar and borders
316
- }
258
+ #ifdef USE_EXPERIMENTAL_WINUI3
259
+ if (m_popUp) {
260
+ return;
261
+ }
262
+ #endif
263
+ // get the root hwnd
264
+ m_prevWindowID =
265
+ winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(view.ReactContext().Properties());
317
266
 
318
- // set the layoutMetrics
319
- m_layoutMetrics.frame.size = {(float)rect.right - rect.left, (float)rect.bottom - rect.top};
320
- m_layoutMetrics.overflowInset.right = 0;
321
- m_layoutMetrics.overflowInset.bottom = 0;
267
+ m_parentHwnd =
268
+ view.as<::Microsoft::ReactNative::Composition::Experimental::IComponentViewInterop>()->GetHwndForParenting();
322
269
 
323
- // get Modal's position based on parent
324
- RECT parentRC;
325
- GetWindowRect(m_parentHwnd, &parentRC);
326
- float xCor = (parentRC.left + parentRC.right - m_layoutMetrics.frame.size.width) / 2; // midpointx - width / 2
327
- float yCor = (parentRC.top + parentRC.bottom - m_layoutMetrics.frame.size.height) / 2; // midpointy - height / 2
270
+ auto portal = view.as<winrt::Microsoft::ReactNative::Composition::PortalComponentView>();
328
271
 
329
- // Adjust window position and size
330
- MoveWindow(m_hwnd, (int)xCor, (int)yCor, (int)(rect.right - rect.left), (int)(rect.bottom - rect.top), true);
272
+ #ifdef USE_EXPERIMENTAL_WINUI3
273
+ m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
274
+ view.Parent().as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor(),
275
+ winrt::Microsoft::UI::GetWindowIdFromWindow(m_parentHwnd));
276
+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(portal);
277
+ auto contentIsland = m_reactNativeIsland.Island();
331
278
 
332
- // Let RNWIsland know that Modal's size has changed
333
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(m_reactNativeIsland)
334
- ->NotifySizeChanged();
335
- };
279
+ m_popUp = m_bridge.TryCreatePopupSiteBridge();
280
+ m_popUp.Connect(contentIsland);
336
281
 
337
- void WindowsModalHostComponentView::updateProps(
338
- facebook::react::Props::Shared const &props,
339
- facebook::react::Props::Shared const &oldProps) noexcept {
340
- const auto &oldModalProps =
341
- *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(oldProps ? oldProps : viewProps());
342
- const auto &newModalProps = *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(props);
343
- newModalProps.visible ? m_isVisible = true : m_isVisible = false;
344
- if (!m_isVisible) {
345
- HideOnUIThread();
282
+ // set the top-level windows as the new hwnd
283
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
284
+ view.ReactContext().Properties(),
285
+ reinterpret_cast<uint64_t>(winrt::Microsoft::UI::GetWindowFromWindowId(m_popUp.WindowId())));
286
+
287
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(
288
+ m_popUp.as<winrt::Microsoft::UI::Content::IContentSiteBridge>());
289
+ m_departFocusToken = navHost.DepartFocusRequested(
290
+ [wkView = winrt::make_weak(view)](
291
+ const auto &sender, const winrt::Microsoft::UI::Input::FocusNavigationRequestEventArgs &args) {
292
+ if (auto strongView = wkView.get()) {
293
+ TrySetFocus(strongView.Parent());
294
+ }
295
+ });
296
+
297
+ #else
298
+ auto presenter = winrt::Microsoft::UI::Windowing::OverlappedPresenter::CreateForDialog();
299
+ presenter.SetBorderAndTitleBar(true, false);
300
+ presenter.IsModal(true);
301
+
302
+ m_window = winrt::Microsoft::UI::Windowing::AppWindow::Create(
303
+ presenter, winrt::Microsoft::UI::GetWindowIdFromWindow(m_parentHwnd));
304
+
305
+ // set the top-level windows as the new hwnd
306
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
307
+ view.ReactContext().Properties(),
308
+ reinterpret_cast<uint64_t>(winrt::Microsoft::UI::GetWindowFromWindowId(m_window.Id())));
309
+
310
+ // create a react native island - code taken from CompositionHwndHost
311
+ m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
312
+ view.Parent().as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor(), m_window.Id());
313
+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(portal);
314
+ auto contentIsland = m_reactNativeIsland.Island();
315
+
316
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(m_bridge);
317
+ m_departFocusToken = navHost.DepartFocusRequested(
318
+ [wkView = winrt::make_weak(view)](
319
+ const auto &sender, const winrt::Microsoft::UI::Input::FocusNavigationRequestEventArgs &args) {
320
+ if (auto strongView = wkView.get()) {
321
+ TrySetFocus(strongView.Parent());
322
+ }
323
+ });
324
+ m_bridge.Connect(contentIsland);
325
+
326
+ #endif
327
+
328
+ m_bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
329
+
330
+ m_islandStateChangedToken =
331
+ contentIsland.StateChanged([weakThis = get_weak()](
332
+ winrt::Microsoft::UI::Content::ContentIsland const &island,
333
+ winrt::Microsoft::UI::Content::ContentIslandStateChangedEventArgs const &args) {
334
+ if (auto pThis = weakThis.get()) {
335
+ if (args.DidRasterizationScaleChange() || args.DidLayoutDirectionChange()) {
336
+ pThis->UpdateConstraints();
337
+ }
338
+ }
339
+ });
340
+
341
+ UpdateConstraints();
342
+
343
+ if (portal.ContentRoot().Children().Size()) {
344
+ AdjustWindowSize(portal.ContentRoot().Children().GetAt(0).LayoutMetrics());
345
+ }
346
+ m_bridge.Show();
346
347
  }
347
- base_type::updateProps(props, oldProps);
348
- }
349
348
 
350
- facebook::react::SharedViewProps WindowsModalHostComponentView::defaultProps() noexcept {
351
- static auto const defaultProps = std::make_shared<facebook::react::ModalHostViewProps const>();
352
- return defaultProps;
353
- }
354
- const facebook::react::ModalHostViewProps &WindowsModalHostComponentView::modalHostViewProps() const noexcept {
355
- return *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(viewProps());
356
- }
357
-
358
- facebook::react::Tag WindowsModalHostComponentView::hitTest(
359
- facebook::react::Point pt,
360
- facebook::react::Point &localPt,
361
- bool ignorePointerEvents) const noexcept {
362
- facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
363
-
364
- if ((ignorePointerEvents || viewProps()->pointerEvents == facebook::react::PointerEventsMode::Auto ||
365
- viewProps()->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
366
- ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
367
- ptLocal.y <= m_layoutMetrics.frame.size.height) {
368
- localPt = ptLocal;
369
- return Tag();
349
+ void UpdateConstraints() noexcept {
350
+ auto displayArea = winrt::Microsoft::UI::Windowing::DisplayArea::GetFromDisplayId(
351
+ m_bridge.SiteView().EnvironmentView().DisplayId());
352
+ auto workArea = displayArea.WorkArea();
353
+
354
+ float scale = m_reactNativeIsland.Island().RasterizationScale();
355
+
356
+ winrt::Microsoft::ReactNative::LayoutConstraints constraints;
357
+ constraints.MinimumSize = {0, 0};
358
+ // Constrain the size of the modal to 90% of the screen size
359
+ constraints.MaximumSize = {
360
+ static_cast<float>((workArea.Width / scale) * 0.9), static_cast<float>((workArea.Height / scale) * 0.9)};
361
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
362
+
363
+ auto layoutDirection = m_reactNativeIsland.Island().LayoutDirection();
364
+ if (layoutDirection == winrt::Microsoft::UI::Content::ContentLayoutDirection::LeftToRight)
365
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::LeftToRight;
366
+ else if (layoutDirection == winrt::Microsoft::UI::Content::ContentLayoutDirection::RightToLeft)
367
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::RightToLeft;
368
+
369
+ // By setting a custom contraint here the behavior of the modal slightly changes.
370
+ // When no constraint is set (maxSize is std::numeric_limits<Float>::infinity()), yoga will layout the content to a
371
+ // desired size If we provide a specific max size, then contents with a flex:1 will expand to fill that size. We
372
+ // might want to provide a windows specific property to control this behavior.
373
+ m_state.UpdateState(winrt::make<ModalHostState>(constraints, m_reactNativeIsland.Island().RasterizationScale()));
370
374
  }
371
375
 
372
- return -1;
373
- }
376
+ static void TrySetFocus(const winrt::Microsoft::ReactNative::ComponentView &view) {
377
+ auto focusController = winrt::Microsoft::UI::Input::InputFocusController::GetForIsland(
378
+ view.as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Root().ReactNativeIsland().Island());
379
+ focusController.TrySetFocus();
380
+ }
374
381
 
375
- bool WindowsModalHostComponentView::focusable() const noexcept {
376
- return false;
377
- }
382
+ ReactContext m_reactContext{nullptr};
383
+ HWND m_parentHwnd{nullptr};
384
+ winrt::Microsoft::UI::Windowing::AppWindow m_window{nullptr};
385
+ uint64_t m_prevWindowID;
386
+ bool m_showTitleBar{false};
387
+ bool m_showQueued{false};
388
+ bool m_mounted{false};
389
+ winrt::event_token m_islandStateChangedToken;
390
+ winrt::Microsoft::UI::Input::InputFocusNavigationHost::DepartFocusRequested_revoker m_departFocusRevoker;
391
+ winrt::event_token m_departFocusToken;
392
+ winrt::event_token m_childLayoutMetricsToken;
393
+ winrt::Microsoft::ReactNative::IComponentState m_state{nullptr};
394
+ winrt::Microsoft::UI::Content::DesktopChildSiteBridge m_bridge{nullptr};
395
+ winrt::Microsoft::ReactNative::ReactNativeIsland m_reactNativeIsland{nullptr};
396
+ #ifdef USE_EXPERIMENTAL_WINUI3
397
+ winrt::Microsoft::UI::Content::PopupWindowSiteBridge m_popUp{nullptr};
398
+ #endif
399
+ };
378
400
 
379
- std::string WindowsModalHostComponentView::DefaultControlType() const noexcept {
380
- return "modal";
401
+ void RegisterWindowsModalHostNativeComponent(
402
+ winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept {
403
+ ::Microsoft::ReactNativeSpecs::RegisterModalHostViewNativeComponent<ModalHostView>(
404
+ packageBuilder,
405
+ [](const winrt::Microsoft::ReactNative::Composition::IReactCompositionViewComponentBuilder &builder) {
406
+ builder.SetPortalComponentViewInitializer(
407
+ [](const winrt::Microsoft::ReactNative::Composition::PortalComponentView &portalComponentView) noexcept {
408
+ auto userData = winrt::make_self<ModalHostView>();
409
+ userData->InitializePortalViewComponent(portalComponentView);
410
+ portalComponentView.UserData(*userData);
411
+ });
412
+ });
381
413
  }
382
414
 
383
415
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation