diff --git a/change/react-native-windows-b59fd8be-3390-42f3-b269-8fce04ab15ae.json b/change/react-native-windows-b59fd8be-3390-42f3-b269-8fce04ab15ae.json new file mode 100644 index 00000000000..826f3dbc917 --- /dev/null +++ b/change/react-native-windows-b59fd8be-3390-42f3-b269-8fce04ab15ae.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Fix XAML bug with alerts inside a dark themed parent", + "packageName": "react-native-windows", + "email": "lyahdav@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/vnext/Microsoft.ReactNative/Modules/AlertModule.cpp b/vnext/Microsoft.ReactNative/Modules/AlertModule.cpp index ae807334e4e..711cae4e849 100644 --- a/vnext/Microsoft.ReactNative/Modules/AlertModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AlertModule.cpp @@ -43,9 +43,12 @@ void Alert::ProcessPendingAlertRequests() noexcept { dialog.DefaultButton(static_cast(defaultButton)); } + auto useXamlRootForThemeBugWorkaround = false; + if (Is19H1OrHigher()) { // XamlRoot added in 19H1 if (const auto xamlRoot = React::XamlUIService::GetXamlRoot(m_context.Properties().Handle())) { + useXamlRootForThemeBugWorkaround = true; dialog.XamlRoot(xamlRoot); auto rootChangedToken = xamlRoot.Changed([=](auto &&, auto &&) { const auto rootSize = xamlRoot.Size(); @@ -71,6 +74,22 @@ void Alert::ProcessPendingAlertRequests() noexcept { } } + // Workaround XAML bug with ContentDialog and dark theme: + // https://github.com/microsoft/microsoft-ui-xaml/issues/2331 + dialog.Opened([useXamlRootForThemeBugWorkaround](winrt::IInspectable const &sender, auto &&) { + auto contentDialog = sender.as(); + auto popups = xaml::Media::VisualTreeHelper::GetOpenPopupsForXamlRoot(contentDialog.XamlRoot()); + + auto contentAsFrameworkElement = useXamlRootForThemeBugWorkaround + ? contentDialog.XamlRoot().Content().try_as() + : xaml::Window::Current().Content().try_as(); + if (contentAsFrameworkElement) { + for (uint32_t i = 0; i < popups.Size(); i++) { + popups.GetAt(i).RequestedTheme(contentAsFrameworkElement.ActualTheme()); + } + } + }); + auto asyncOp = dialog.ShowAsync(); asyncOp.Completed( [jsDispatcher, result, this](