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 b60f47ef5a3..000e1f3c111 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 @@ -282,6 +283,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(); @@ -365,6 +384,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 { @@ -380,6 +402,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 fc14c896fe0..75b34bd89ad 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h @@ -204,6 +204,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;