diff --git a/change/react-native-windows-6efd65a3-c7b2-4fee-b9d9-d6dac48f59b9.json b/change/react-native-windows-6efd65a3-c7b2-4fee-b9d9-d6dac48f59b9.json new file mode 100644 index 00000000000..c3635cdab66 --- /dev/null +++ b/change/react-native-windows-6efd65a3-c7b2-4fee-b9d9-d6dac48f59b9.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Fix Button visibility in dark mode by adding theme-aware root background (#15521)", + "packageName": "react-native-windows", + "email": "nitchaudhary@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp index 54b9ff491b1..3f566aa5552 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp @@ -32,6 +32,7 @@ #include "ReactNativeHost.h" #include "RootComponentView.h" #include "TextDrawing.h" +#include "Theme.h" #include #include @@ -281,6 +282,24 @@ void ReactNativeIsland::UpdateRootVisualSize() noexcept { UpdateDebuggerVisualSize(); } +void ReactNativeIsland::UpdateRootVisualBackground() noexcept { + if (m_rootVisual && m_theme) { + // Set a theme-aware background color on the root visual. + // This ensures that semi-transparent WinUI colors (like Button's ControlFillColorDefault) + // render correctly against the proper theme background, matching native WinUI app behavior. + // See Issue #15521: Button becomes invisible in dark mode. + auto themeImpl = winrt::get_self(m_theme); + auto backgroundColor = themeImpl->PlatformColor("SolidBackgroundFillColorBase"); + auto spriteVisual = m_rootVisual.as(); + if (spriteVisual) { + auto compContext = + winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::CreateContext( + m_compositor); + spriteVisual.Brush(compContext.CreateColorBrush(backgroundColor)); + } + } +} + void ReactNativeIsland::UpdateLoadingVisualSize() noexcept { if (m_loadingVisual) { auto drawingSurface = CreateLoadingVisualBrush(); @@ -364,6 +383,9 @@ void ReactNativeIsland::Theme(const winrt::Microsoft::ReactNative::Composition:: const winrt::Windows::Foundation::IInspectable & /*sender*/, const winrt::Windows::Foundation::IInspectable & /*args*/) { if (auto strongThis = wkThis.get()) { + // Update the root visual background when theme changes (light/dark mode switch) + strongThis->UpdateRootVisualBackground(); + if (auto rootView = strongThis->GetComponentView()) { Mso::Functor fn = [](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept { @@ -379,6 +401,9 @@ void ReactNativeIsland::Theme(const winrt::Microsoft::ReactNative::Composition:: } }); + // Update the root visual background with the new theme + UpdateRootVisualBackground(); + if (auto rootView = GetComponentView()) { rootView->theme(winrt::get_self(value)); } diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h index 3428495527b..f7bbef69a6a 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h @@ -203,6 +203,7 @@ struct ReactNativeIsland void ShowDebuggerUI(std::string message, const std::function &onResume) noexcept; void HideDebuggerUI() noexcept; void UpdateRootVisualSize() noexcept; + void UpdateRootVisualBackground() noexcept; void UpdateLoadingVisualSize() noexcept; void UpdateDebuggerVisualSize() noexcept; Composition::Experimental::IDrawingSurfaceBrush CreateLoadingVisualBrush() noexcept;