@@ -37,6 +37,13 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
3737 m_window.Destroy ();
3838 m_window = nullptr ;
3939 }
40+
41+ #ifdef USE_EXPERIMENTAL_WINUI3
42+ if (m_popUp) {
43+ m_popUp.Close ();
44+ m_popUp = nullptr ;
45+ }
46+ #endif
4047 }
4148
4249 void InitializePortalViewComponent (
@@ -85,7 +92,6 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
8592 private:
8693 void OnMounted (const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
8794 m_mounted = true ;
88-
8995 if (m_showQueued) {
9096 ShowOnUIThread (view);
9197 }
@@ -108,11 +114,20 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
108114 int32_t yCor = static_cast <int32_t >(
109115 (parentRC.top + parentRC.bottom - layoutMetrics.Frame .Height * layoutMetrics.PointScaleFactor ) / 2 );
110116
117+ #ifdef USE_EXPERIMENTAL_WINUI3
118+ winrt::Windows::Graphics::RectInt32 rect2{
119+ (int )xCor,
120+ (int )yCor,
121+ static_cast <int32_t >(layoutMetrics.Frame .Width * (layoutMetrics.PointScaleFactor )),
122+ static_cast <int32_t >(layoutMetrics.Frame .Height * (layoutMetrics.PointScaleFactor ))};
123+ m_popUp.MoveAndResize (rect2);
124+ #else
111125 // Adjust window position and size
112126 m_window.ResizeClient (
113127 {static_cast <int32_t >(layoutMetrics.Frame .Width * (layoutMetrics.PointScaleFactor )),
114128 static_cast <int32_t >(layoutMetrics.Frame .Height * (layoutMetrics.PointScaleFactor ))});
115129 m_window.Move ({xCor, yCor});
130+ #endif
116131 };
117132
118133 void ShowOnUIThread (const winrt::Microsoft::ReactNative::ComponentView &view) {
@@ -122,6 +137,24 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
122137 m_showQueued = false ;
123138 EnsureModalCreated (view);
124139
140+ #ifdef USE_EXPERIMENTAL_WINUI3
141+ if (m_popUp) {
142+ m_bridge.Enable ();
143+ m_popUp.Show ();
144+
145+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge (
146+ m_popUp.as <winrt::Microsoft::UI::Content::IContentSiteBridge>());
147+ auto result = navHost.NavigateFocus (winrt::Microsoft::UI::Input::FocusNavigationRequest::Create (
148+ winrt::Microsoft::UI::Input::FocusNavigationReason::First));
149+
150+ // dispatch onShow event
151+ if (auto eventEmitter = EventEmitter ()) {
152+ ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnShow eventArgs;
153+ eventEmitter->onShow (eventArgs);
154+ }
155+ }
156+ #endif
157+
125158 if (m_window && !m_window.IsVisible ()) {
126159 m_bridge.Enable ();
127160 m_window.Show (true );
@@ -146,6 +179,12 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
146179 m_window.Hide ();
147180 }
148181
182+ #ifdef USE_EXPERIMENTAL_WINUI3
183+ if (m_popUp) {
184+ m_popUp.Hide ();
185+ }
186+ #endif
187+
149188 // dispatch onDismiss event
150189 if (auto eventEmitter = EventEmitter ()) {
151190 ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnDismiss eventArgs;
@@ -168,13 +207,45 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
168207 return ;
169208 }
170209
210+ #ifdef USE_EXPERIMENTAL_WINUI3
211+ if (m_popUp) {
212+ return ;
213+ }
214+ #endif
171215 // get the root hwnd
172216 m_prevWindowID =
173217 winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId (view.ReactContext ().Properties ());
174218
175219 m_parentHwnd =
176220 view.as <::Microsoft::ReactNative::Composition::Experimental::IComponentViewInterop>()->GetHwndForParenting ();
177221
222+ #ifdef USE_EXPERIMENTAL_WINUI3
223+ m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create (
224+ view.Parent ().as <winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor (),
225+ winrt::Microsoft::UI::GetWindowIdFromWindow (m_parentHwnd));
226+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal (
227+ view.as <winrt::Microsoft::ReactNative::Composition::PortalComponentView>());
228+ auto contentIsland = m_reactNativeIsland.Island ();
229+
230+ m_popUp = m_bridge.TryCreatePopupSiteBridge ();
231+ m_popUp.Connect (contentIsland);
232+
233+ // set the top-level windows as the new hwnd
234+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId (
235+ view.ReactContext ().Properties (),
236+ reinterpret_cast <uint64_t >(winrt::Microsoft::UI::GetWindowFromWindowId (m_popUp.WindowId ())));
237+
238+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge (
239+ m_popUp.as <winrt::Microsoft::UI::Content::IContentSiteBridge>());
240+ m_departFocusToken = navHost.DepartFocusRequested (
241+ [wkView = winrt::make_weak (view)](
242+ const auto &sender, const winrt::Microsoft::UI::Input::FocusNavigationRequestEventArgs &args) {
243+ if (auto strongView = wkView.get ()) {
244+ TrySetFocus (strongView.Parent ());
245+ }
246+ });
247+
248+ #else
178249 auto presenter = winrt::Microsoft::UI::Windowing::OverlappedPresenter::CreateForDialog ();
179250 presenter.SetBorderAndTitleBar (true , false );
180251 presenter.IsModal (true );
@@ -202,9 +273,11 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
202273 TrySetFocus (strongView.Parent ());
203274 }
204275 });
276+ m_bridge.Connect (contentIsland);
277+
278+ #endif
205279
206280 m_bridge.ResizePolicy (winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
207- m_bridge.Connect (contentIsland);
208281 AdjustWindowSize (view.LayoutMetrics ());
209282 m_bridge.Show ();
210283 }
@@ -226,6 +299,9 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
226299 winrt::event_token m_departFocusToken;
227300 winrt::Microsoft::UI::Content::DesktopChildSiteBridge m_bridge{nullptr };
228301 winrt::Microsoft::ReactNative::ReactNativeIsland m_reactNativeIsland{nullptr };
302+ #ifdef USE_EXPERIMENTAL_WINUI3
303+ winrt::Microsoft::UI::Content::PopupWindowSiteBridge m_popUp{nullptr };
304+ #endif
229305};
230306
231307void RegisterWindowsModalHostNativeComponent (
0 commit comments