microsoft / microsoft/microsoft-ui-reactor

[Bug] RichTextBlock.Foreground has no ThemeRef overload, so .Foreground(Theme.X) is silently dropped

Open
#1,002 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C#
Stars
646
Forks
54
Avg merge
1d 3h
Merged PRs (30d)
84

Description

Split out of #961, whose sample-side scope was fixed by #963 (5 genuine sites) and #970/#950 (the 7 reclassified gate-class sites). This framework gap was explicitly *"not counted among the 12"* there and is the only part of #961 that had not landed, so it is being carried here rather than keeping that issue open for it.

### What happened?

`samples/apps/demo-script-tool/App/Components/StepCard.cs:124` does:

```csharp
BuildCodeRichText(step.Code, Props.PriorStep?.Code)
.Foreground(Theme.PrimaryText)
```

`ElementExtensions` declares two `RichTextBlockElement` overloads and no more — `ElementExtensions.cs:743` (`string`) and `:746` (`Brush`). `Theme.PrimaryText` is a `ThemeRef`, so the call falls through to the **generic common modifier**, whose gate at `Reconciler.cs:3917-3925` is `Control` / `TextBlock`:

```csharp
if (m.Foreground is not null && !ReferenceEquals(m.Foreground, oldM?.Foreground))
{
if (fe is WinUI.Control fgCtrl) fgCtrl.Foreground = m.Foreground;
else if (fe is TextBlock fgTb) fgTb.Foreground = m.Foreground;
}
```

`RichTextBlock` is neither, so the write is silently dropped and the sample renders with the default foreground.

**The sample is correct here** — it is using a theme token, which is exactly what the theming rules ask for. The fix belongs in the framework: add the missing `ThemeRef` overload rather than rewriting the sample to a hard-coded brush.

`REACTOR_MOD_003` reports this as 1 of the 90 sites in the sample sweep, categorised as *framework — missing overload*.

### Steps to reproduce

1. Check out current `main`.
2. In `samples/.editorconfig`, raise the scoped `dotnet_diagnostic.REACTOR_MOD_003.severity = suggestion` entry to `warning`.
3. `dotnet build Reactor.slnx -c Debug`
4. Filter the log for `REACTOR_MOD_003` and look for `StepCard.cs`:
```
...\Components\StepCard.cs(124,22): warning REACTOR_MOD_003:
'Foreground' has no effect on 'RichTextBlockElement' — Reactor only applies
'Foreground' to Control or TextBlock
```
5. Or run `samples/apps/demo-script-tool` and observe the code block in a step card renders with the default foreground rather than `Theme.PrimaryText`.

### Suggested fix

Add `Foreground(this RichTextBlockElement el, ThemeRef theme)` alongside the existing `string` / `Brush` overloads in `src/Reactor/Elements/ElementExtensions.cs`, resolving through the same theming path the `TextBlockElement` `ThemeRef` overload uses.

Worth deciding at the same time whether the *generic* gate at `Reconciler.cs:3917` should grow `RichTextBlock` as well, since `RichTextBlock.Foreground` is a real WinUI DP — that would fix the whole family rather than one overload, and is the same "widen the gate vs. add a shim" question #950 settled for `Padding`.

Notes:
- New public API surface means regenerating the two byte-identical index copies (`skills/reactor.api.txt` and `plugins/reactor/skills/reactor-dsl/references/reactor.api.txt`) via `mur --regen-api`.
- Coverage wants a selftest, not a unit test — headless xUnit cannot construct a WinUI `RichTextBlock`. Assert the resolved `Foreground` brush on the live control so the check fails if the write is dropped again.

### Reactor version / commit

`3f85ca49` (`main`)

### Platform

x64

### .NET SDK version

10.0.302

### Windows version

N/A — reproduces as a build-time diagnostic and a render difference, not a version-specific fault.

### Windows App SDK version

2.1.3

### Logs / stack trace

```
...\App\Components\StepCard.cs(124,22): warning REACTOR_MOD_003:
'Foreground' has no effect on 'RichTextBlockElement' — Reactor only applies
'Foreground' to Control or TextBlock
```

### Confirmation

- [x] I have searched existing issues and this isn't a duplicate.
- [x] This bug reproduces against the current `main` branch.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/Reactor/Elements/ElementExtensions.cs around the RichTextBlockElement Foreground overloads, then inspect the common modifier gate in Reconciler.cs:3917-3925 and the existing TextBlockElement ThemeRef path. Check the live-control selftest coverage and the two reactor.api.txt copies. Done means Theme.PrimaryText is applied to RichTextBlock, the regression check passes, and generated API indexes remain synchronized.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.