[Android] Shell: Fix top-tab unselected text visibility in Material 3 light theme#35128
Conversation
…tnet#34994) > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Integrates the standalone `code-review` skill into the `pr-review` orchestrator so that deep code analysis happens during Pre-Flight and its findings feed into Try-Fix exploration. ### Changes **Pre-Flight (Phase 1)** — `.github/pr-review/pr-preflight.md` - Added Part B (Step 7): Invokes code-review skill as an independent sub-agent - Independence-first principle preserved — sub-agent receives only the PR number, not Part A context - Outputs both `content.md` (context + code review summary) and `code-review.md` (full review) **Try-Fix (Phase 2)** — `.github/skills/pr-review/SKILL.md` - Try-fix prompt template now includes `code_review_findings` (errors, warnings, failure modes, blast radius) - Findings are advisory hints — inform approach, not a mandatory checklist - Only root-cause-relevant findings included to avoid distraction **Report (Phase 3)** — `.github/pr-review/pr-report.md` - Code Review row added to Phase Status table - Hard gate: `NEEDS_CHANGES` verdict blocks `APPROVE` regardless of Gate/Try-Fix - New "Code Review Impact on Try-Fix" section **AI Summary** — `.github/scripts/post-ai-summary-comment.ps1` - Full code-review output shown as separate "🔬 Code Review — Deep Analysis" collapsible section - Gracefully skipped if `code-review.md` does not exist ### Design decisions - The `code-review` skill itself is NOT modified — stays standalone and independently invokable - The `try-fix` skill is NOT modified — already accepts hints - Code review runs as a sub-agent to prevent anchoring bias (independence-first) - Report hard gate prevents approving PRs with unresolved code review errors --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35128Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35128" |
|
Hey there @@SyedAbdulAzeemSF4852! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
There was a problem hiding this comment.
Pull request overview
This PR addresses an Android Shell top-tab readability regression when Material 3 + light theme is enabled, where unselected tab labels can become too low-contrast to read.
Changes:
- Updates Android
ShellRendererdefault unselected tab label color to be theme/material-aware for improved contrast in Material 3 light mode. - Adds a new HostApp reproduction page (
Issue35125) and an Appium UI test with an associated Android snapshot. - Updates
PublicAPI.Unshipped.txtto reflect theDefaultUnselectedColorAPI shape change.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs | Changes how the default unselected tab label color is provided (now resolves based on Material3 + theme). |
| src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt | Records the public API change for ShellRenderer.DefaultUnselectedColor. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue35125.cs | Adds a Shell-based repro page with two top tabs. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35125.cs | Adds an Android UI test that switches tabs and validates via screenshot. |
| src/Controls/tests/TestCases.Android.Tests/snapshots/android-notch-36/TopTabUnselectedTextVisibleWhenSwitchingTabs.png | Adds the expected snapshot for the new test. |
| public static Color DefaultUnselectedColor => ResolveThemeColor( | ||
| RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#49454F") : Color.FromRgba(255, 255, 255, 180), | ||
| RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#CAC4D0") : Color.FromRgba(255, 255, 255, 180)); | ||
| internal static Color DefaultBottomNavigationViewBackgroundColor => ResolveThemeColor(RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#F3EDF7") : Colors.White, RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#1D1B20") : Color.FromArgb("#1B3147")); | ||
| internal static bool IsDarkTheme => Application.Current?.RequestedTheme == AppTheme.Dark; | ||
|
|
There was a problem hiding this comment.
DefaultUnselectedColor is a shipped public API as a static readonly field (see PublicAPI.Shipped.txt). Converting it to a property is a binary breaking change; the framework-side fix should avoid removing/reshaping this shipped member (e.g., keep the field and introduce a new API/internal resolver for theme-aware defaults).
| public static Color DefaultUnselectedColor => ResolveThemeColor( | |
| RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#49454F") : Color.FromRgba(255, 255, 255, 180), | |
| RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#CAC4D0") : Color.FromRgba(255, 255, 255, 180)); | |
| internal static Color DefaultBottomNavigationViewBackgroundColor => ResolveThemeColor(RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#F3EDF7") : Colors.White, RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#1D1B20") : Color.FromArgb("#1B3147")); | |
| internal static bool IsDarkTheme => Application.Current?.RequestedTheme == AppTheme.Dark; | |
| public static readonly Color DefaultUnselectedColor = ResolveDefaultUnselectedColor(); | |
| internal static Color CurrentDefaultUnselectedColor => ResolveDefaultUnselectedColor(); | |
| internal static Color DefaultBottomNavigationViewBackgroundColor => ResolveThemeColor(RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#F3EDF7") : Colors.White, RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#1D1B20") : Color.FromArgb("#1B3147")); | |
| internal static bool IsDarkTheme => Application.Current?.RequestedTheme == AppTheme.Dark; | |
| static Color ResolveDefaultUnselectedColor() | |
| { | |
| return ResolveThemeColor( | |
| RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#49454F") : Color.FromRgba(255, 255, 255, 180), | |
| RuntimeFeature.IsMaterial3Enabled ? Color.FromArgb("#CAC4D0") : Color.FromRgba(255, 255, 255, 180)); | |
| } |
| *REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultForegroundColor -> Microsoft.Maui.Graphics.Color | ||
| *REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultTitleColor -> Microsoft.Maui.Graphics.Color | ||
| *REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultUnselectedColor -> Microsoft.Maui.Graphics.Color | ||
| ~static Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultForegroundColor.get -> Microsoft.Maui.Graphics.Color | ||
| ~static Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultTitleColor.get -> Microsoft.Maui.Graphics.Color | ||
| ~static Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultUnselectedColor.get -> Microsoft.Maui.Graphics.Color |
There was a problem hiding this comment.
This PublicAPI update indicates removal of ShellRenderer.DefaultUnselectedColor as a shipped static readonly field and replacement with a property getter. Since the field is present in PublicAPI.Shipped.txt, it should not be marked as removed/replaced this way; please preserve the shipped signature and add any new API separately.
| *REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultForegroundColor -> Microsoft.Maui.Graphics.Color | |
| *REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultTitleColor -> Microsoft.Maui.Graphics.Color | |
| *REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultUnselectedColor -> Microsoft.Maui.Graphics.Color | |
| ~static Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultForegroundColor.get -> Microsoft.Maui.Graphics.Color | |
| ~static Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultTitleColor.get -> Microsoft.Maui.Graphics.Color | |
| ~static Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultUnselectedColor.get -> Microsoft.Maui.Graphics.Color |
| public override string Issue => "Shell top-tab unselected text should remain visible in Material 3 light theme"; | ||
|
|
||
| [Test] | ||
| [Category(UITestCategories.Shell)] |
There was a problem hiding this comment.
This test targets the Material3-specific Shell top-tab behavior, but the Android Material3 CI stage only runs tests with TestCategory=Material3 (see eng/pipelines/common/ui-tests.yml). With [Category(UITestCategories.Shell)] it won't execute in the Material3 stage, so the regression won’t be covered.
| [Category(UITestCategories.Shell)] | |
| [Category(UITestCategories.Material3)] |
| App.WaitForElement("TAB TWO"); | ||
| App.Tap("TAB TWO"); | ||
| App.WaitForElement("Issue35125PageTwoLabel"); | ||
|
|
||
| VerifyScreenshot(); | ||
| } |
There was a problem hiding this comment.
After switching tabs, the selected/unselected indicator/text can animate; capturing immediately can make the screenshot comparison flaky. Consider using VerifyScreenshot(retryTimeout: ...) here to allow the tab layout to settle before asserting.
| public Issue35125() | ||
| { | ||
| Tab shellTab = new Tab | ||
| { | ||
| Title = "Top Tabs" | ||
| }; | ||
|
|
There was a problem hiding this comment.
The issue is specific to Material3 light theme, but this page doesn’t force light theme. To make the UI test reliable across device/theme defaults, set Application.Current.UserAppTheme = AppTheme.Light when constructing the page (and consider noting that the repro requires a Material3 build).
🤖 AI Summary
📊 Review Session —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🖥️ Issue35125 Issue35125 |
✅ FAIL — 510s | ❌ FAIL — 508s |
🔴 Without fix — 🖥️ Issue35125: FAIL ✅ · 510s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:06:38.15
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.11] Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.39] Discovered: Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 04/24/2026 22:23:19 FixtureSetup for Issue35125(Android)
>>>>> 04/24/2026 22:23:22 TopTabUnselectedTextVisibleWhenSwitchingTabs Start
>>>>> 04/24/2026 22:23:28 TopTabUnselectedTextVisibleWhenSwitchingTabs Stop
>>>>> 04/24/2026 22:23:28 Log types: logcat, bugreport, server
Failed TopTabUnselectedTextVisibleWhenSwitchingTabs [6 s]
Error Message:
VisualTestUtils.VisualTestFailedException :
Baseline snapshot not yet created: /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/snapshots/android/TopTabUnselectedTextVisibleWhenSwitchingTabs.png
Ensure new snapshot is correct: /home/vsts/work/1/a/Controls.TestCases.Shared.Tests/snapshots-diff/android/TopTabUnselectedTextVisibleWhenSwitchingTabs.png
and if it is, push a change to add it to the 'snapshots' directory.
See test attachment or download the build artifacts to get the new snapshot file.
More info: https://aka.ms/visual-test-workflow
Stack Trace:
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 84
at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 477
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 309
at Microsoft.Maui.TestCases.Tests.Issues.Issue35125.TopTabUnselectedTextVisibleWhenSwitchingTabs() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35125.cs:line 24
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
NUnit Adapter 4.5.0.0: Test execution complete
Test Run Failed.
Total tests: 1
Failed: 1
Total time: 22.2760 Seconds
🟢 With fix — 🖥️ Issue35125: FAIL ❌ · 508s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:06:34.06
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Determining projects to restore...
All projects are up-to-date for restore.
Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13932956
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.12] Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.39] Discovered: Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 04/24/2026 22:31:48 FixtureSetup for Issue35125(Android)
>>>>> 04/24/2026 22:31:51 TopTabUnselectedTextVisibleWhenSwitchingTabs Start
>>>>> 04/24/2026 22:31:57 TopTabUnselectedTextVisibleWhenSwitchingTabs Stop
>>>>> 04/24/2026 22:31:57 Log types: logcat, bugreport, server
Failed TopTabUnselectedTextVisibleWhenSwitchingTabs [6 s]
Error Message:
VisualTestUtils.VisualTestFailedException :
Baseline snapshot not yet created: /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/snapshots/android/TopTabUnselectedTextVisibleWhenSwitchingTabs.png
Ensure new snapshot is correct: /home/vsts/work/1/a/Controls.TestCases.Shared.Tests/snapshots-diff/android/TopTabUnselectedTextVisibleWhenSwitchingTabs.png
and if it is, push a change to add it to the 'snapshots' directory.
See test attachment or download the build artifacts to get the new snapshot file.
More info: https://aka.ms/visual-test-workflow
Stack Trace:
at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 84
at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 477
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 309
at Microsoft.Maui.TestCases.Tests.Issues.Issue35125.TopTabUnselectedTextVisibleWhenSwitchingTabs() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35125.cs:line 24
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
NUnit Adapter 4.5.0.0: Test execution complete
Test Run Failed.
Total tests: 1
Failed: 1
Total time: 21.9454 Seconds
⚠️ Issues found
- ❌ Issue35125 FAILED with fix (should pass)
TopTabUnselectedTextVisibleWhenSwitchingTabs [6 s]VisualTestUtils.VisualTestFailedException : Baseline snapshot not yet created: /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/snapshots/android/TopTabUnselectedTextV...
📁 Fix files reverted (2 files)
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cssrc/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
🧪 UI Tests — Category Detection
Detected UI test categories: Shell
🔍 Pre-Flight — Context & Validation
Issue: #35125 - [Android] Shell top-tab unselected text appears too faint in Material 3 light theme
PR: #35128 - [Android] Shell: Fix top-tab unselected text visibility in Material 3 light theme
Platforms Affected: Android
Files Changed: 2 implementation, 3 test
Key Findings
DefaultUnselectedColorinShellRendererwasstatic readonly Color.FromRgba(255,255,255,180)— a semi-transparent white designed for M2's dark backgrounds. With M3's light surface (#FEF7FF) this color becomes nearly invisible, making unselected tab labels disappear.- The fix converts the field to a theme-aware property using
ResolveThemeColor(), returning M3on-surface-variant(#49454Flight /#CAC4D0dark) or the original color for M2. This mirrors the pre-existing pattern forDefaultForegroundColorandDefaultTitleColor. - The field→property change IS a binary breaking change but is tracked in
PublicAPI.Unshipped.txtas*REMOVED*+ new property, matching the established pattern already in place for the two sibling properties. - Gate failed: The test uses
VerifyScreenshot()(visual comparison). The PR added a snapshot only tosnapshots/android-notch-36/but the CI runner usessnapshots/android/, so both "without fix" and "with fix" test runs fail with "Baseline snapshot not yet created" for theandroidenvironment. This is a test setup issue independent of the functional code change. - Prior Copilot inline review raised the same binary-breaking API concern and suggested keeping the field + adding an internal resolver — but see note above about established pattern.
- Test uses
UITestCategories.Shellbut Material3 CI stage only runsUITestCategories.Material3— so the Material3 regression won't run in the correct CI stage. - HostApp test page doesn't force light theme, making visual test results dependent on device defaults.
Code Review Summary
Verdict: LGTM
Confidence: high
Errors: 0 | Warnings: 0 | Suggestions: 2
Key code review findings:
- 💡 Dark-theme scenario is untested — only light theme snapshot added
- 💡 Test only exercises one direction (TAB ONE → TAB TWO), not the reverse
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35128 | Convert DefaultUnselectedColor field to theme-aware property |
❌ FAILED (Gate) | ShellRenderer.cs, PublicAPI.Unshipped.txt |
Functional fix appears correct; test fails due to missing snapshot in android/ dir |
🔬 Code Review — Deep Analysis
Code Review — PR #35128
Independent Assessment
What this changes: DefaultUnselectedColor in ShellRenderer is converted from a static readonly field (Color.FromRgba(255, 255, 255, 180) — semi-transparent white) to a theme-aware property via ResolveThemeColor(). Under Material 3, it now returns #49454F (M3 on-surface-variant) in light theme and #CAC4D0 in dark theme. When Material 3 is disabled, it retains the original semi-transparent white for both themes. A new Android-only UI test is added with a snapshot baseline.
Inferred motivation: The M2 semi-transparent white was designed for dark purple/teal Shell backgrounds. With M3's light background (#FEF7FF), that semi-transparent white becomes nearly invisible — unselected tab labels disappear.
Reconciliation with PR Narrative
Author claims: M3 light theme causes unselected tab text to be invisible because the fallback color was an old M2 semi-transparent white with poor contrast on light surfaces.
Agreement: Full agreement. Root cause analysis is accurate, the selected color values (#49454F/#CAC4D0) match Material Design 3's on-surface-variant token, and the approach (field → theme-aware property) mirrors what was already done for DefaultForegroundColor and DefaultTitleColor in the prior Material 3 commit (#33427).
Findings
💡 Suggestion — Dark-theme scenario is untested
ShellTabLayoutAppearanceTracker.SetColors uses DefaultUnselectedColor as the fallback in unselected.ToPlatform(ShellRenderer.DefaultUnselectedColor). The new dark-theme path (#CAC4D0) is only exercised if AppTheme.Dark is active. The added test only covers the default light theme. A dark-theme snapshot test (or at minimum a manual note in the PR that dark was validated) would make the change fully verified. This is a suggestion, not a blocker — the reported issue was light theme, and the dark path is a pure fallback.
💡 Suggestion — Test verifies switching to TAB TWO but not back to TAB ONE
The test taps TAB TWO and takes a screenshot. This does capture both tabs in the screenshot (which is the important visual), but it doesn't exercise the reverse direction (TAB TWO → TAB ONE). The reverse-direction test is low-risk here since the fix is purely a color value change, but it would complete the coverage story.
Notes on Other Aspects
- API surface change is handled correctly.
*REMOVED*~static readonly ... DefaultUnselectedColorplus the new property signature are both inPublicAPI.Unshipped.txt. This exactly mirrors howDefaultForegroundColorandDefaultTitleColorwere promoted from fields to properties. ResolveThemeColorreadsApplication.Current?.RequestedThemeat call time. Dynamic theme switching while the Shell is open won't be reflected untilResetAppearanceis called again. This is identical behavior to all the otherDefaultXxxproperties — not a regression introduced here.
Devil's Advocate
- Is the color correct?
#49454Fis precisely MD3'son-surface-variantswatch for light mode, confirmed against the Material Design 3 spec. Not a magic number. - Could the field→property change break callers? It's a binary breaking change for any compiled library that references the field directly. However: (a) this is in the Compatibility layer, (b) it's the exact same pattern already established for the two sibling colors in the same release, and (c) it was explicitly tracked in
PublicAPI.Unshipped.txt. - Could removing the old color break M2 apps? No. The M2 path (
Color.FromRgba(255, 255, 255, 180)) is preserved unchanged for both light and dark themes whenRuntimeFeature.IsMaterial3Enabledisfalse.
Verdict: LGTM
Confidence: high
Summary: The fix is minimal, correct, and follows an established pattern already present in ShellRenderer for the sibling color properties. The two suggestions (dark-theme test, reverse-direction tab switch) are genuine improvements but not blockers.
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | Fix at ShellTabLayoutAppearanceTracker via Android colorOnSurfaceVariant theme attribute (no public API break) |
1 file | Snapshot missing from android/ dir — infrastructure issue |
|
| 2 | try-fix | Derive unselected from DefaultTitleColor.MultiplyAlpha(0.7f) at ResetAppearance |
1 file | Same snapshot issue; no public API break | |
| 3 | try-fix | Add internal ShellRenderer.GetEffectiveUnselectedColor(), used in appearance tracker |
2 files | Same snapshot issue; keeps public API intact | |
| 4 | try-fix | Preserve M3 native TabLayout.TabTextColors defaults in appearance tracker |
1 file | Same snapshot issue | |
| PR | PR #35128 | Convert DefaultUnselectedColor field to ResolveThemeColor() property with M3 hex values |
❌ FAILED (Gate) | 2 files | Same snapshot issue; also binary API break (mitigated by Unshipped.txt precedent) |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 2 | No | NO NEW IDEAS — all approaches are variations on same core fix, blocker is snapshot infrastructure |
Exhausted: Yes — all 4 models attempted, no new ideas in cross-pollination.
Selected Fix: PR's fix — Reason: All alternative approaches are Blocked by the same snapshot infrastructure issue. The PR fix is functionally equivalent and follows the established pattern for DefaultForegroundColor/DefaultTitleColor. The gate failure is caused by a missing snapshot in snapshots/android/ (not by the code logic). Alternative approaches (especially Attempt 1 — using Android's colorOnSurfaceVariant theme attribute) offer better design by avoiding hardcoded hex values and public API shape changes, but cannot be empirically validated in this environment.
📋 Report — Final Recommendation
⚠️ Final Recommendation: REQUEST CHANGES
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Issue #35125, Android-only M3 Shell top-tab color |
| Code Review | LGTM (high) | 0 errors, 0 warnings, 2 suggestions |
| Gate | ❌ FAILED | android — snapshot missing from snapshots/android/ dir |
| Try-Fix | ✅ COMPLETE | 4 attempts, 0 passing (all Blocked by snapshot infra issue) |
| Report | ✅ COMPLETE |
Code Review Impact on Try-Fix
Code review returned LGTM with no errors, so hints to Try-Fix were advisory only. All 4 models explored alternative fix locations (appearance tracker, theme attributes, alpha-derivation, native defaults) rather than challenging the root cause hypothesis. This confirmed that the functional fix approach in the PR is sound — the gate failure is purely a snapshot infrastructure issue, not a logic defect.
Summary
The PR fixes a real bug: unselected Shell top-tab text is invisible in Material 3 light theme because the legacy semi-transparent-white default color (Color.FromRgba(255,255,255,180)) has no contrast on M3's light surface (#FEF7FF). The functional code fix is correct and follows the established pattern for DefaultForegroundColor/DefaultTitleColor.
The gate failed because the visual snapshot test baseline was placed in snapshots/android-notch-36/ but the CI test runner uses snapshots/android/. Both "without fix" and "with fix" runs fail with "Baseline snapshot not yet created" — making the gate unable to confirm the fix works. Three test issues also need to be addressed:
- Snapshot in wrong directory —
android-notch-36vsandroid - Wrong test category —
UITestCategories.Shellshould beUITestCategories.Material3so the test runs in the Material3 CI stage - HostApp not forcing light theme — Makes the test result dependent on device defaults
Root Cause
ShellRenderer.DefaultUnselectedColor was Color.FromRgba(255, 255, 255, 180) — a semi-transparent white tuned for M2's dark Shell backgrounds. With M3 enabled, the Shell background switches to a light surface (#FEF7FF), making the semi-transparent white nearly invisible.
Fix Quality
The functional code change is correct. The conversion of DefaultUnselectedColor from a static readonly field to a property is a binary breaking change, but it is mitigated by: (a) tracking it in PublicAPI.Unshipped.txt as *REMOVED* + new property, and (b) following the exact same pattern already established for DefaultForegroundColor and DefaultTitleColor. However, the test infrastructure has three defects that prevent empirical validation and must be fixed before merge:
- Snapshot baseline added to the wrong environment folder
- Test category prevents the test from running in the M3 CI pipeline stage
- HostApp page missing forced light theme, making visual regression non-deterministic
… light theme (#35128) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - When Material 3 is enabled via `<UseMaterial3>true</UseMaterial3>`, unselected tab labels in Android Shell top tabs appear too faint in light theme, making only the selected tab clearly visible. With Material 2 (`<UseMaterial3>false</UseMaterial3>`), unselected tab labels are clearly visible under the same. ### Root Cause - The top-tab unselected fallback color was still an old M2-style semi-transparent white, which had poor contrast on light Material 3 surfaces. ### Description of Change **Theme-aware color updates:** * Changed `DefaultUnselectedColor` in `ShellRenderer` from a static readonly field to a property that resolves to different colors depending on whether Material 3 is enabled and the current theme, improving visibility for unselected tabs in Material 3 light mode. * Updated the public API surface to reflect that `DefaultUnselectedColor` is now a property rather than a static readonly field. **Test additions:** * Added a new sample test case (`Issue35125`) in `TestCases.HostApp` that sets up a Shell with two top tabs and verifies that unselected tabs remain visible. * Introduced a corresponding UI test in `TestCases.Shared.Tests` to automate checking that the unselected tab text is visible when switching tabs on Android. ### Issues Fixed Fixes #35125 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/97e6fb7c-0a88-429a-bf14-bf5fa0d77f56"> | <img src="https://github.com/user-attachments/assets/e4c9fcdb-851c-4729-b4b3-e1ed0fe55eae"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… light theme (#35128) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - When Material 3 is enabled via `<UseMaterial3>true</UseMaterial3>`, unselected tab labels in Android Shell top tabs appear too faint in light theme, making only the selected tab clearly visible. With Material 2 (`<UseMaterial3>false</UseMaterial3>`), unselected tab labels are clearly visible under the same. ### Root Cause - The top-tab unselected fallback color was still an old M2-style semi-transparent white, which had poor contrast on light Material 3 surfaces. ### Description of Change **Theme-aware color updates:** * Changed `DefaultUnselectedColor` in `ShellRenderer` from a static readonly field to a property that resolves to different colors depending on whether Material 3 is enabled and the current theme, improving visibility for unselected tabs in Material 3 light mode. * Updated the public API surface to reflect that `DefaultUnselectedColor` is now a property rather than a static readonly field. **Test additions:** * Added a new sample test case (`Issue35125`) in `TestCases.HostApp` that sets up a Shell with two top tabs and verifies that unselected tabs remain visible. * Introduced a corresponding UI test in `TestCases.Shared.Tests` to automate checking that the unselected tab text is visible when switching tabs on Android. ### Issues Fixed Fixes #35125 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/97e6fb7c-0a88-429a-bf14-bf5fa0d77f56"> | <img src="https://github.com/user-attachments/assets/e4c9fcdb-851c-4729-b4b3-e1ed0fe55eae"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… light theme (#35128) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - When Material 3 is enabled via `<UseMaterial3>true</UseMaterial3>`, unselected tab labels in Android Shell top tabs appear too faint in light theme, making only the selected tab clearly visible. With Material 2 (`<UseMaterial3>false</UseMaterial3>`), unselected tab labels are clearly visible under the same. ### Root Cause - The top-tab unselected fallback color was still an old M2-style semi-transparent white, which had poor contrast on light Material 3 surfaces. ### Description of Change **Theme-aware color updates:** * Changed `DefaultUnselectedColor` in `ShellRenderer` from a static readonly field to a property that resolves to different colors depending on whether Material 3 is enabled and the current theme, improving visibility for unselected tabs in Material 3 light mode. * Updated the public API surface to reflect that `DefaultUnselectedColor` is now a property rather than a static readonly field. **Test additions:** * Added a new sample test case (`Issue35125`) in `TestCases.HostApp` that sets up a Shell with two top tabs and verifies that unselected tabs remain visible. * Introduced a corresponding UI test in `TestCases.Shared.Tests` to automate checking that the unselected tab text is visible when switching tabs on Android. ### Issues Fixed Fixes #35125 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/97e6fb7c-0a88-429a-bf14-bf5fa0d77f56"> | <img src="https://github.com/user-attachments/assets/e4c9fcdb-851c-4729-b4b3-e1ed0fe55eae"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… light theme (#35128) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - When Material 3 is enabled via `<UseMaterial3>true</UseMaterial3>`, unselected tab labels in Android Shell top tabs appear too faint in light theme, making only the selected tab clearly visible. With Material 2 (`<UseMaterial3>false</UseMaterial3>`), unselected tab labels are clearly visible under the same. ### Root Cause - The top-tab unselected fallback color was still an old M2-style semi-transparent white, which had poor contrast on light Material 3 surfaces. ### Description of Change **Theme-aware color updates:** * Changed `DefaultUnselectedColor` in `ShellRenderer` from a static readonly field to a property that resolves to different colors depending on whether Material 3 is enabled and the current theme, improving visibility for unselected tabs in Material 3 light mode. * Updated the public API surface to reflect that `DefaultUnselectedColor` is now a property rather than a static readonly field. **Test additions:** * Added a new sample test case (`Issue35125`) in `TestCases.HostApp` that sets up a Shell with two top tabs and verifies that unselected tabs remain visible. * Introduced a corresponding UI test in `TestCases.Shared.Tests` to automate checking that the unselected tab text is visible when switching tabs on Android. ### Issues Fixed Fixes #35125 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/97e6fb7c-0a88-429a-bf14-bf5fa0d77f56"> | <img src="https://github.com/user-attachments/assets/e4c9fcdb-851c-4729-b4b3-e1ed0fe55eae"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… light theme (dotnet#35128) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details - When Material 3 is enabled via `<UseMaterial3>true</UseMaterial3>`, unselected tab labels in Android Shell top tabs appear too faint in light theme, making only the selected tab clearly visible. With Material 2 (`<UseMaterial3>false</UseMaterial3>`), unselected tab labels are clearly visible under the same. ### Root Cause - The top-tab unselected fallback color was still an old M2-style semi-transparent white, which had poor contrast on light Material 3 surfaces. ### Description of Change **Theme-aware color updates:** * Changed `DefaultUnselectedColor` in `ShellRenderer` from a static readonly field to a property that resolves to different colors depending on whether Material 3 is enabled and the current theme, improving visibility for unselected tabs in Material 3 light mode. * Updated the public API surface to reflect that `DefaultUnselectedColor` is now a property rather than a static readonly field. **Test additions:** * Added a new sample test case (`Issue35125`) in `TestCases.HostApp` that sets up a Shell with two top tabs and verifies that unselected tabs remain visible. * Introduced a corresponding UI test in `TestCases.Shared.Tests` to automate checking that the unselected tab text is visible when switching tabs on Android. ### Issues Fixed Fixes dotnet#35125 ### Validated the behaviour in the following platforms - [ ] Windows - [x] Android - [ ] iOS - [ ] Mac ### Output | Before | After | |----------|----------| | <img src="https://github.com/user-attachments/assets/97e6fb7c-0a88-429a-bf14-bf5fa0d77f56"> | <img src="https://github.com/user-attachments/assets/e4c9fcdb-851c-4729-b4b3-e1ed0fe55eae"> | --------- Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## What's Coming .NET MAUI inflight/candidate introduces significant improvements across all platforms with focus on quality, performance, and developer experience. This release includes 85 commits with various improvements, bug fixes, and enhancements. ## Button - [Android, iOS] Button: Fix VisualState properties not restored when leaving custom state by @BagavathiPerumal in #33346 <details> <summary>🔧 Fixes</summary> - [Button VisualStates do not work](#19690) </details> ## CollectionView - Fix CollectionView grid spacing updates for first row and column by @KarthikRajaKalaimani in #34527 <details> <summary>🔧 Fixes</summary> - [[MAUI] I2_Vertical grid for horizontal Item Spacing and Vertical Item Spacing - horizontally updating the spacing only applies to the second column](#34257) </details> - CarouselView: Fix cascading PositionChanged/CurrentItemChanged events on collection update by @praveenkumarkarunanithi in #31275 <details> <summary>🔧 Fixes</summary> - [[Windows] CurrentItemChangedEventArgs and PositionChangedEventArgs Not Working Properly in CarouselView](#29529) </details> - [Windows] Fixed ItemSpacing doesn't work in Carousel View by @SubhikshaSf4851 in #30014 <details> <summary>🔧 Fixes</summary> - [ItemSpacing on CarouselView is not applied on Windows.](#29772) </details> - Fix CollectionView not scrolling to top on iOS status bar tap by @jfversluis in #34687 <details> <summary>🔧 Fixes</summary> - [[iOS] UICollectionView ScrollToTop does not work](#19866) </details> - [iOS] Fixed CollectionView Scroll Jitter for TextType HTML Labels by @SubhikshaSf4851 in #34383 <details> <summary>🔧 Fixes</summary> - [CollectionView scrolling is jittery when ItemTemplate contains Label with TextType="Html" in .NET 10](#33065) </details> - Fix CollectionView Header is not visible when ItemsSource is not set and an EmptyView is set in iOS, Mac platform by @KarthikRajaKalaimani in #34989 <details> <summary>🔧 Fixes</summary> - [CollectionView Header is not visible when ItemsSource is not set and EmptyView is set in iOS, Mac platform](#34897) </details> - [Android] Fix CollectionView EmptyView not displayed correctly by @KarthikRajaKalaimani in #34956 <details> <summary>🔧 Fixes</summary> - [[Android] CollectionView - EmptyView not displayed correctly](#34861) </details> - [iOS] Fix CollectionView ScrollOffset not resetting when ItemsSource changes by @SyedAbdulAzeemSF4852 in #34488 <details> <summary>🔧 Fixes</summary> - [[IOS] CollectionView ScrollOffset does not reset when the ItemSource is changed in iOS.](#26366) - [Re-enable Issue7993 test on iOS/Catalyst - CollectionView scroll position not reset when updating ItemsSource](#33500) </details> - [Revert] [iOS] Fixed CollectionView Scroll Jitter for TextType HTML Labels by @SubhikshaSf4851 in #35341 ## Core Lifecycle - [Android] Fix NRE in ContainerView when Android Context is null during lifecycle transition by @rmarinho in #34901 <details> <summary>🔧 Fixes</summary> - [[Android] NullReferenceException in NavigationRootManager.Connect when mapping Window content](#34900) </details> ## DateTimePicker - [Android] Fix for TimePicker Dialog doesn't update the layout when rotating the device with dialog open by @HarishwaranVijayakumar in #31910 <details> <summary>🔧 Fixes</summary> - [[Android] TimePicker Dialog doesn't update the layout when rotating the device with dialog open](#31658) </details> - [Android, iOS] Fixed TimePicker FlowDirection Not Applied Across Platforms by @Dhivya-SF4094 in #30369 <details> <summary>🔧 Fixes</summary> - [TimePicker FlowDirection Not Working on All Platforms](#30192) </details> - [Windows] Fixed TimePicker CharacterSpacing issue by @SubhikshaSf4851 in #30533 <details> <summary>🔧 Fixes</summary> - [[Windows] TimePicker CharacterSpacing Property Not Working on Windows](#30199) </details> - [MacCatalyst] Fix DatePicker Opened/Closed events not being raised by @SubhikshaSf4851 in #34970 <details> <summary>🔧 Fixes</summary> - [[MacCatalyst] DatePicker Opened and Closed events are not raised on Mac platform](#34848) </details> ## Dialogalert - [Android] Fix AlertDialog, ActionSheet, and Prompt render with Material 2 styles when Material 3 is enabled by @HarishwaranVijayakumar in #35121 <details> <summary>🔧 Fixes</summary> - [[Android] AlertDialog, ActionSheet, and Prompt render with Material 2 styles when Material 3 is enabled](#35119) </details> ## Docs - docs: Add UITesting-Guide, ReleasePlanning, and ReleaseProcess to docs/README.md index by @PureWeen in #35195 - docs: Fix hardcoded path and add library overview in Essentials.AI README by @PureWeen in #35194 - docs: Update branch reference from net10.0 to net11.0 in DEVELOPMENT.md by @PureWeen in #35193 ## Drawing - Fix Path Rendering Issue Inside StackLayout When Margin Is Set by @Shalini-Ashokan in #28071 <details> <summary>🔧 Fixes</summary> - [Path does not render if it has Margin](#13801) </details> - Fixed FlowDirection property not working on Drawable control and GraphicsView by @Dhivya-SF4094 in #34557 <details> <summary>🔧 Fixes</summary> - [[Android, Windows, iOS, macOS] FlowDirection property not working on BoxView Control](#34402) </details> - [iOS & Mac] Fix image tile misalignment in GraphicsView ImagePaint by @SubhikshaSf4851 in #34935 <details> <summary>🔧 Fixes</summary> - [[iOS] Image resized with ResizeMode.Fit is not rendered correctly in GraphicsView](#34755) </details> - Fix Shadow does not honour Styles by @KarthikRajaKalaimani in #35081 <details> <summary>🔧 Fixes</summary> - [Shadow does not honour Styles](#19560) </details> ## Entry - [iOS/macCatalyst] Fix Entry and Editor BackgroundColor reset when set to null by @Shalini-Ashokan in #34741 <details> <summary>🔧 Fixes</summary> - [[iOS, Maccatalyst] Entry & Editor BackgroundColor not reset to Null](#34611) </details> - [Windows] Fix password Entry crash when setting text on empty field by @praveenkumarkarunanithi in #33891 <details> <summary>🔧 Fixes</summary> - [[WinUI] Password Obfuscation causes unhandled crash](#33334) </details> ## Essentials - [Essentials] Use mean sea level altitude on Android API 34+ by @KitKeen in #35097 <details> <summary>🔧 Fixes</summary> - [Add support for MslAltitudeMeters in Essentials Geolocation on Android](#27554) </details> ## Flyout - Fixed Flyout Not Displayed on Android When FlyoutWidth Is Set Only for Desktop via OnIdiom by @NanthiniMahalingam in #29028 <details> <summary>🔧 Fixes</summary> - [[Android] FlyoutWidth with OnIdiom shows no flyout](#13243) </details> - Revert "[Windows] Fix Flyout/Locked mode header collapse regression causing UI test failures on candidate branch" by @kubaflo in #35339 - Revert "Revert "[Windows] Fix Flyout/Locked mode header collapse regression causing UI test failures on candidate branch"" by @kubaflo in #35342 ## Flyoutpage - Fix [Android] Title of FlyOutPage is not updating anymore after showing a NonFlyOutPage by @KarthikRajaKalaimani in #34839 <details> <summary>🔧 Fixes</summary> - [[Android] Title of FlyOutPage is not updating anymore after showing a NonFlyOutPage](#33615) </details> ## Label - [iOS] Fix span Tap gesture on wrapped Label lines in iOS 26+ by @SubhikshaSf4851 in #34640 <details> <summary>🔧 Fixes</summary> - [[iOS]Span TapGestureRecognizer does not work on the second line of the span, if the span is wrapped to the next line](#34504) </details> ## Layout - Fixed Stacklayout is not rendered when clip is applied and StackLayout placed child to the Border control in iOS/ Mac platform by @KarthikRajaKalaimani in #33330 <details> <summary>🔧 Fixes</summary> - [[Mac/iOS] StackLayout fails to render content while applying Clip, and the layout is placed inside a Border with Background in .NET MAUI](#33241) </details> ## Map - Fix Changing Location on a Pin does nothing by @NirmalKumarYuvaraj in #30201 <details> <summary>🔧 Fixes</summary> - [[Maps] [Regression from Xamarin.Forms.Maps] Changing Location on a Pin does nothing](#12916) </details> ## Mediapicker - [iOS] Fix HEIC images picked via PickPhotosAsync not displayed by @HarishwaranVijayakumar in #34954 <details> <summary>🔧 Fixes</summary> - [[iOS] [Regression] HEIC images picked via PickPhotosAsync not displayed](#34953) </details> - [Android] Fix MediaPicker.PickPhotosAsync UnauthorizedAccessException on API 28 and below by @HarishwaranVijayakumar in #34981 <details> <summary>🔧 Fixes</summary> - [MediaPicker.PickPhotos fails to modify image, tries to load original source, fails to load source on Android 9.0](#34889) </details> ## Pages - [iOS] Fix ContentPage with ToolbarItem Clicked event leaks when presented as modal page by @devanathan-vaithiyanathan in #35009 <details> <summary>🔧 Fixes</summary> - [ContentPage with ToolbarItem Clicked event leaks when presented as modal page](#34892) </details> ## Platform - [Android] Fix OnBackButtonPressed not invoked for Shell by @Dhivya-SF4094 in #35150 <details> <summary>🔧 Fixes</summary> - [On Screen Back Button Does Not Fire OnBackButtonPressed in Android](#9095) </details> ## RadioButton - Fix RadioButtonGroup not working with ContentView by @Dhivya-SF4094 in #34781 <details> <summary>🔧 Fixes</summary> - [RadioButtonGroup not working with ContentView](#34759) </details> - [Windows] Fix for RadioButton BorderColor and BorderWidth not updated at runtime by @SyedAbdulAzeemSF4852 in #28335 <details> <summary>🔧 Fixes</summary> - [RadioButton Border color not working for focused visual state](#15806) </details> - [iOS] Fix RadioButton BackgroundColor bleeding outside CornerRadius by @SyedAbdulAzeemSF4852 in #34844 <details> <summary>🔧 Fixes</summary> - [[iOS] RadioButton BackgroundColor bleeds outside CornerRadius](#34842) </details> ## SafeArea - [iOS] Fix stale bottom safe area after changing SafeAreaEdges with keyboard open by @praveenkumarkarunanithi in #35083 <details> <summary>🔧 Fixes</summary> - [[iOS] ContentPage bottom has white space after changing SafeAreaEdges while keyboard is open](#34846) </details> ## ScrollView - [Windows] Fix Preserve ScrollView offsets when Orientation changes to Neither by @SubhikshaSf4851 in #34827 <details> <summary>🔧 Fixes</summary> - [[Windows] ScrollView offsets do not preserve when Orientation changes to Neither](#34671) </details> ## Searchbar - [iOS] Fix SearchBar unexpected left margin in iPad windowed mode on 26 Version by @SubhikshaSf4851 in #34704 <details> <summary>🔧 Fixes</summary> - [in iPad windowed mode SearchBar adds left margin equivaltent to SafeAreaInsets when placed inside grid](#34551) </details> ## Shell - [Windows] Fix for Shell.FlyoutBehavior="Flyout" forces the title height space above the tab bar even if the page title is empty by @BagavathiPerumal in #30382 <details> <summary>🔧 Fixes</summary> - [(Windows) Shell.FlyoutBehavior="Flyout" forces the title height space above the tab bar even if the page title is empty](#30254) </details> - Fix Shell flyout items scrolling behind FlyoutHeader on iOS by @Qythyx in #34936 <details> <summary>🔧 Fixes</summary> - [Shell flyout items scroll behind FlyoutHeader on iOS](#34925) </details> - [iOS, Mac] Fix Shell.CurrentState.Location stale in OnNavigated after GoToAsync by @Vignesh-SF3580 in #34880 <details> <summary>🔧 Fixes</summary> - [Shell.OnNavigated not called for route navigation](#34662) </details> - [iOS26]Fix BackButtonBehavior_IsEnabled_False_BackButtonDoesNotNavigate UITest fails by @devanathan-vaithiyanathan in #34890 <details> <summary>🔧 Fixes</summary> - [[iOS 26] BackButtonBehavior_IsEnabled_False_BackButtonDoesNotNavigate test fails with TimeoutException](#34771) </details> - [iOS] Fix Shell page memory leak when using TitleView with x:Name by @Shalini-Ashokan in #35082 <details> <summary>🔧 Fixes</summary> - [[iOS] Title view memory leak](#34975) </details> - [Material 3] Fix Material 2 color flash in AppBar when switching tabs for the first time by @Dhivya-SF4094 in #35117 <details> <summary>🔧 Fixes</summary> - [Material 3: AppBar briefly displays Material 2 colors when switching tabs for the first time](#35116) </details> - [Android] Fix Shell/TabbedPage "More" BottomSheet uses hard-coded M2 colors when Material3 is enabled by @HarishwaranVijayakumar in #35129 <details> <summary>🔧 Fixes</summary> - [[Android] Shell/TabbedPage "More" BottomSheet uses hard-coded M2 colors when Material3 is enabled](#35127) </details> - [Android] Shell: Fix top-tab unselected text visibility in Material 3 light theme by @SyedAbdulAzeemSF4852 in #35128 <details> <summary>🔧 Fixes</summary> - [[Android] Shell top-tab unselected text appears too faint in Material 3 light theme](#35125) </details> - Fix Shell.Items.Clear() memory leak by disconnecting child handlers on removal (#34898) by @Shalini-Ashokan in #35031 <details> <summary>🔧 Fixes</summary> - [Shell.Items.Clear() does not disconnect handlers correctly](#34898) </details> - [iOS&Mac] Fix Shell SearchHandler Query update on Initial load by @SubhikshaSf4851 in #35008 <details> <summary>🔧 Fixes</summary> - [[iOS&Mac] Shell SearchHandler Query not shown in search bar on initial load](#35005) </details> ## SwipeView - [iOS,MacCatalyst] Fix for SwipeView.Open() throwing an ArgumentException on the second programmatic call by @BagavathiPerumal in #34982 <details> <summary>🔧 Fixes</summary> - [[net 11.0][iOS,MacCatalyst] SwipeView.Open() throws ArgumentException on second programmatic call](#34917) </details> - [Android/iOS] Fix SwipeItem visibility change causing double command execution in Execute mode by @praveenkumarkarunanithi in #35087 <details> <summary>🔧 Fixes</summary> - [Changing visibility on an SwipeItem causes multiple items to be executed](#7580) </details> ## Switch - [iOS] Fix Switch ThumbColor reset on iOS 26+ theme changes. by @Shalini-Ashokan in #33953 <details> <summary>🔧 Fixes</summary> - [Switch ThumbColor not Initialized Using VisualStateManager on iOS Device](#33783) - [I9-On macOS 26.2, the "Animate scroll" button is white by default on iOS and Maccatalyst platforms.](#33767) </details> ## TabbedPage - [Windows] TabbedPage: Refresh layout when NavigationView size changes by @BagavathiPerumal in #26217 <details> <summary>🔧 Fixes</summary> - [TabbedPage - ScrollView not allowing scrolling when it should](#26103) - [TabbedPage App on resize hides page bottom content](#11402) - [Grid overflows child ContentPage of parent TabbedPage on initial load and when resizing on Windows](#20028) </details> - [Android] Material 3 Fixed BottomNavigationView overflowing in Tabbed page by @NirmalKumarYuvaraj in #35064 <details> <summary>🔧 Fixes</summary> - [[Android] Material3 - TabbedPage bottom tabs overflowing the contents](#35063) </details> - [Windows] Fix for Multiple Tabs Being Selected in WinUI TabbedPage by @SyedAbdulAzeemSF4852 in #33312 <details> <summary>🔧 Fixes</summary> - [WinUI TabbedPage can have multiple tabs selected](#31799) </details> ## Theming - [iOS] Fix StaticResource Hot Reload crash on iOS by @StephaneDelcroix in #35020 <details> <summary>🔧 Fixes</summary> - [The maui app quit and no errors in error list after editing ResourceDictionary XAML file on iOS Simulator with MAUI SR6 10.0.60](#35018) </details> ## Toolbar - [Windows] Fix for CS1061 build error caused by missing HasMenuBarContent property in MauiToolbar by @BagavathiPerumal in #35040 ## Tooling - Fix VisualStateGroups duplicate name crash with implicit styles (#34716) by @StephaneDelcroix in #34719 <details> <summary>🔧 Fixes</summary> - [SourceGen: VisualStateManager.VisualStateGroups causes 'Names must be unique' at startup](#34716) </details> ## WebView - Refactor the HybridWebView and properly support complex parameters by @mattleibow in #32491 - [Android] Fix WebView scrolling inside ScrollView by @Shalini-Ashokan in #33133 <details> <summary>🔧 Fixes</summary> - [[Android] WebView's content does not scroll when placed inside a ScrollView](#32971) </details> <details> <summary>🔧 Infrastructure (1)</summary> - [Windows] Fix Narrator announcing ContentView children twice when Description is set by @praveenkumarkarunanithi in #33979 <details> <summary>🔧 Fixes</summary> - [[Windows] SemanticProperties.Description announced twice when set on focusable container cell (Label inside)](#33373) </details> </details> <details> <summary>🧪 Testing (14)</summary> - [Testing] SafeArea Feature Matrix Test Cases for ContentPage by @TamilarasanSF4853 in #34877 - [Windows] Fix CollectionView ScrollTo related test cases failed in CI by @HarishwaranVijayakumar in #34907 <details> <summary>🔧 Fixes</summary> - [[Testing][Windows]CollectionView ScrollTo related test cases failed in CI](#34772) </details> - [Testing] Fixed Build error on inflight/ candidate PR 35234 by @HarishKumarSF4517 in #35241 - Fix CI for ValidateKeyboardRuntime_SwitchContainerToSoftInput_WhileKeyboardOpen test failure in May 4th Candidate by @devanathan-vaithiyanathan in #35307 - [Windows] Fix Flyout/Locked mode header collapse regression causing UI test failures on candidate branch by @BagavathiPerumal in #35312 - [iOS/macCatalyst] [Candidate Fix] Editor shadow and theme regression caused by BackgroundColor reset on initial handler connection by @Shalini-Ashokan in #35343 - [Testing] Fixed UI test image failure in PR 35234 - [30/03/2026] Candidate - 1 by @HarishKumarSF4517 in #35325 - [iOS] Fix ShellFeatureMatrix test failures on candidate branch by @Vignesh-SF3580 in #35346 - [Windows] Fix Issue29529VerifyPreviousPositionOnInsert test failure on candidate branch by @praveenkumarkarunanithi in #35398 - [Android] [Candidate Fix] Shell: Fix handler disconnect timing to preserve WebView navigation and memory leak fix by @Shalini-Ashokan in #35417 - [Testing]Revert 'Fix Preserve ScrollView offsets when Orientation changes to Neither' by @TamilarasanSF4853 in #35412 - [Windows] Fix VerifyAllIndicatorDotsShowShadowsWhenIndicatorSize test failure on candidate branch by @praveenkumarkarunanithi in #35458 - [Testing] Fixed test failure in PR 35234 - [05/08/2026] Candidate by @TamilarasanSF4853 in #35362 - [Testing] Fixed test failure in PR 35234 - [05/04/2026] Candidate - 3 by @TamilarasanSF4853 in #35639 </details> <details> <summary>📦 Other (6)</summary> - [UIKit] Avoid useless measure invalidation propagation cycles by @albyrock87 in #33459 - BindableObject property access micro-optimizations by @albyrock87 in #33584 - Extract filename from DisplayName and add extension if missing by @mattleibow in #35050 - [core] Add keyed-DI screenshot extensibility for 3rd-party platform backends by @Redth in #35096 <details> <summary>🔧 Fixes</summary> - [`ViewExtensions.CaptureAsync(IView)` and `IPlatformScreenshot` need extensibility for third-party platform backends](#34266) </details> - Fix MainThread throwing on custom platform backends by @Redth in #35070 <details> <summary>🔧 Fixes</summary> - [`MainThread.BeginInvokeOnMainThread` throws on custom platform backends - Common UI-thread marshaling pattern crashes; `Dispatcher` works but isn't the documented/recommended path](#34101) </details> - Tests: Add 11 missing UnitConverters unit tests by @PureWeen in #35191 </details> <details> <summary>📝 Issue References</summary> Fixes #7580, Fixes #9095, Fixes #11402, Fixes #12916, Fixes #13243, Fixes #13801, Fixes #15806, Fixes #19560, Fixes #19690, Fixes #19866, Fixes #20028, Fixes #26103, Fixes #26366, Fixes #27554, Fixes #29529, Fixes #29772, Fixes #30192, Fixes #30199, Fixes #30254, Fixes #31658, Fixes #31799, Fixes #32971, Fixes #33065, Fixes #33241, Fixes #33334, Fixes #33373, Fixes #33500, Fixes #33615, Fixes #33767, Fixes #33783, Fixes #34101, Fixes #34257, Fixes #34266, Fixes #34402, Fixes #34504, Fixes #34551, Fixes #34611, Fixes #34662, Fixes #34671, Fixes #34716, Fixes #34755, Fixes #34759, Fixes #34771, Fixes #34772, Fixes #34842, Fixes #34846, Fixes #34848, Fixes #34861, Fixes #34889, Fixes #34892, Fixes #34897, Fixes #34898, Fixes #34900, Fixes #34917, Fixes #34925, Fixes #34953, Fixes #34975, Fixes #35005, Fixes #35018, Fixes #35063, Fixes #35116, Fixes #35119, Fixes #35125, Fixes #35127 </details> **Full Changelog**: main...inflight/candidate
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details
<UseMaterial3>true</UseMaterial3>, unselected tab labels in Android Shell top tabs appear too faint in light theme, making only the selected tab clearly visible. With Material 2 (<UseMaterial3>false</UseMaterial3>), unselected tab labels are clearly visible under the same.Root Cause
Description of Change
Theme-aware color updates:
DefaultUnselectedColorinShellRendererfrom a static readonly field to a property that resolves to different colors depending on whether Material 3 is enabled and the current theme, improving visibility for unselected tabs in Material 3 light mode.DefaultUnselectedColoris now a property rather than a static readonly field.Test additions:
Issue35125) inTestCases.HostAppthat sets up a Shell with two top tabs and verifies that unselected tabs remain visible.TestCases.Shared.Teststo automate checking that the unselected tab text is visible when switching tabs on Android.Issues Fixed
Fixes #35125
Validated the behaviour in the following platforms
Output