microsoft / microsoft/microsoft-ui-reactor

REACTOR_A11Y_003 doesn't accept fluent .Header(...) as a label, and doesn't cover ComboBox/ToggleSwitch

Open
#1,007 0 comments 0 reactions 0 assignees View on GitHub
accessibility analyzer
Dominant language
C#
Stars
646
Forks
54
Avg merge
1d 3h
Merged PRs (30d)
84

Description

## Context

Found while fixing #981, where four ReactorGallery cards shipped a bare `ComboBox` / `ToggleSwitch` and UIA reported `Name: (null)`. The interesting question isn't the samples — it's why nothing caught them.

`FormFieldLabelAnalyzer` (`REACTOR_A11Y_003`, `src/Reactor.Analyzers/AccessibilityAnalyzers.cs` ~L222-236) exists precisely to catch unlabelled form fields, and it was running on those files. It stayed silent for two independent reasons.

## Gap 1 — control coverage

The rule covers `TextBox`, `NumberBox`, `PasswordBox`, `AutoSuggestBox`. It does not cover `ComboBox` or `ToggleSwitch`, both of which are form fields that need an accessible name just as much.

## Gap 2 — the fluent `.Header(...)` modifier isn't recognised as a label

This one is worth fixing regardless of Gap 1, because it produces **false positives on correct code**. The analyzer accepts:

- the `header:` named argument
- `.AutomationName(...)`
- `.LabeledBy(...)`

but **not** the fluent `.Header("...")` modifier — even though it is the idiomatic Reactor spelling and demonstrably drives the UIA Name. Verified live in #981 via `HeaderAutomationNameFixtures`:

```
# HAN ComboBox: bare=<> headed= headedPlaceholder= headedEditable=
# HAN ToggleSwitch: bare=<> header=
```

So today `TextBox(...).Header("Name")` is correctly labelled but still diagnosed, while `TextBox(..., header: "Name")` is not. Two spellings of the same thing, one flagged.

## Why this wasn't fixed inline with #981

Deliberately deferred rather than smuggled into an a11y samples PR — the blast radius is real and deserves its own review:

- `samples/Directory.Build.props` wires the analyzer into **every** sample project.
- The repo root `Directory.Build.props` sets `TreatWarningsAsErrors` in **Release**.

So widening control coverage turns roughly 30 existing bare `ComboBox(...)` / `ToggleSwitch(...)` call sites across `samples/` into **Release build errors** in one step. And a good number are **false positives**: `SamplePageHost.OptionPanel` already derives `.AutomationName(...)` from a preceding caption `TextBlock` at runtime, which a syntactic analyzer cannot see. Those call sites are genuinely accessible today; flagging them would train contributors to suppress the rule, which is worse than not having it.

## Suggested sequencing

1. **Fix Gap 2 first, on its own.** Accept `.Header(...)` as a satisfying label for the controls already covered. Pure false-positive reduction, no new diagnostics, safe to land immediately.
2. **Then Gap 1**, with the sample fallout handled in the same PR — either label the real cases or find a way for the analyzer not to fire on `OptionPanel`-hosted children (an opt-out marker, or recognising the host pattern).
3. Add a row to `src/Reactor.Analyzers/AnalyzerReleases.Unshipped.md` if the id's behaviour changes materially, and note that `src/Reactor.Analyzers` targets `netstandard2.0` and cannot reference `src/Reactor.Cli` — any shared logic needs copying plus parity tests.

## Acceptance

- `TextBox(...).Header("Name")` no longer reports `REACTOR_A11Y_003`.
- A bare `ComboBox(...)` / `ToggleSwitch(...)` with no label does report it.
- `OptionPanel`-hosted children in `samples/` do not report it.
- `dotnet build -c Release` stays green across the solution.

Contributor guide

Open the contributing guide

Research direction

Start in src/Reactor.Analyzers/AccessibilityAnalyzers.cs around FormFieldLabelAnalyzer and inspect the HeaderAutomationNameFixtures evidence, then review the sample call sites and Directory.Build.props files for Release warning behavior. Update the analyzer and its tests so fluent Header is accepted, bare ComboBox and ToggleSwitch controls are covered without flagging OptionPanel-hosted children, and dotnet build -c Release stays green.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
accessibility, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.