From 6f39227b73aaa8cde92dea9cd6c41cb94171ac80 Mon Sep 17 00:00:00 2001 From: Nitin Chaudhary Date: Wed, 7 Jan 2026 15:11:36 +0530 Subject: [PATCH 1/3] Fix Button visibility in dark mode (#15521) --- .../Fabric/Composition/ReactNativeIsland.cpp | 30 +++++++++++++++++-- .../Fabric/Composition/ReactNativeIsland.h | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp index 54b9ff491b1..fc3886c38c8 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)); } @@ -921,8 +946,9 @@ winrt::Microsoft::UI::Content::ContentIsland ReactNativeIsland::Island() { if (auto pThis = weakThis.get()) { if (auto rootView = pThis->GetComponentView()) { args.Result( - rootView->NavigateFocus(winrt::Microsoft::ReactNative::FocusNavigationRequest( - winrt::Microsoft::ReactNative::FocusNavigationReason::First)) + rootView->NavigateFocus( + winrt::Microsoft::ReactNative::FocusNavigationRequest( + winrt::Microsoft::ReactNative::FocusNavigationReason::First)) ? winrt::Microsoft::UI::Input::FocusNavigationResult::Moved : winrt::Microsoft::UI::Input::FocusNavigationResult::NotMoved); } else { 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; From e96460217b65922886b4521bd69fedc25e38474c Mon Sep 17 00:00:00 2001 From: Nitin Chaudhary Date: Wed, 7 Jan 2026 15:17:06 +0530 Subject: [PATCH 2/3] Change files --- ...ative-windows-6efd65a3-c7b2-4fee-b9d9-d6dac48f59b9.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-6efd65a3-c7b2-4fee-b9d9-d6dac48f59b9.json 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" +} From 591313107a3b43213f546198ea1a7b8fe38c3b7b Mon Sep 17 00:00:00 2001 From: Nitin Chaudhary Date: Wed, 7 Jan 2026 16:28:16 +0530 Subject: [PATCH 3/3] Format code --- .../Fabric/Composition/ReactNativeIsland.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp index fc3886c38c8..3f566aa5552 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp @@ -946,9 +946,8 @@ winrt::Microsoft::UI::Content::ContentIsland ReactNativeIsland::Island() { if (auto pThis = weakThis.get()) { if (auto rootView = pThis->GetComponentView()) { args.Result( - rootView->NavigateFocus( - winrt::Microsoft::ReactNative::FocusNavigationRequest( - winrt::Microsoft::ReactNative::FocusNavigationReason::First)) + rootView->NavigateFocus(winrt::Microsoft::ReactNative::FocusNavigationRequest( + winrt::Microsoft::ReactNative::FocusNavigationReason::First)) ? winrt::Microsoft::UI::Input::FocusNavigationResult::Moved : winrt::Microsoft::UI::Input::FocusNavigationResult::NotMoved); } else {