Skip to content

Add typed ResourceBuilder overloads for native styling values - #1370

Merged
Alexandre Zollinger Chohfi (azchohfi) merged 3 commits into
microsoft:mainfrom
kusutori:feat/resource-builder-value-overloads
Oct 21, 2026
Merged

Alexandre Zollinger Chohfi (azchohfi) merged 3 commits into
microsoft:mainfrom
kusutori:feat/resource-builder-value-overloads

Conversation

@kusutori

Copy link
Copy Markdown
Contributor

Summary

Add the missing typed ResourceBuilder.Set overloads for Thickness, FontWeight, FontFamily, bool, Color, and GridLength, completing the common non-brush styling surface described by spec 015.

  • Preserve literal value types and existing color-string/brush/ThemeRef behavior; no generic catch-all or int overload.
  • Add unit tests and native WinUI fixtures covering typed values, mount/update/removal, control reuse, unmanaged-resource preservation, and BreadcrumbBar usage.
  • Update the styling guide through its template and regenerate both API index copies.

Linked issue / spec

Fixes #1369

Related: spec 015.

Test plan

  • Release x64 builds of the unit-test project and native selftest host.
  • LightweightStylingTests: 20 passed, 0 failed/skipped.
  • TypedResource_ WinUI selftests: 2 fixtures, 27 checks passed.
  • Temporarily no-op the Thickness overload: its targeted test failed; restore the implementation and rerun the 20-test class successfully.
  • Compile the styling topic and verify the two generated API indexes are identical.
  • Downstream Tonarink Release x64 publish and Debug mur devtools inspection: native BreadcrumbBar resources retain the expected types and values.

Validation was focused on this change; the full solution/suites, MSIX, and Native AOT were not run locally. The unit-test build reported the upstream test graph's existing NU1902/NU1903 warnings for System.Security.Cryptography.Pkcs 9.0.6; package versions and auditing settings were not changed.

Risk / breaking changes

Additive overloads only. Existing integer arguments still select double; string arguments still create brushes. Reconciliation and theme resolution are unchanged.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, the typed overloads fill a real gap. A few things to address inline: FontFamily equality across renders, making the Color overload's intent explicit, proving template consumption in the BreadcrumbBar fixture, and syncing the design specs plus a FontFamily example in the guide.

Comment thread src/Reactor/Elements/ResourceBuilder.cs
Comment thread src/Reactor/Elements/ResourceBuilder.cs
Comment thread tests/Reactor.AppTests.Host/SelfTest/Fixtures/TypedResourceOverrideFixtures.cs Outdated
Comment thread docs/_pipeline/templates/styling.md.dt Outdated
Comment thread docs/_pipeline/templates/styling.md.dt
@kusutori

kusutoriクスとり (kusutori) commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks Alexandre Zollinger Chohfi (@azchohfi) for the detailed feedback! Addressed the review in 51dfc4f:

  • Compare FontFamily literals by Source, with equal/different checks using freshly allocated families, plus value-equality checks for the five new value types
  • Rename the literal-color overload to SetColor, keeping the distinction from brush resources explicit in the API and documentation
  • Probe the rendered BreadcrumbBar label and template chevron after layout, alongside an unstyled baseline, rather than only reading the resource dictionary
  • Update the design specs, implementation checklist, generated guide and both API indexes, including an explicit new FontFamily(...) example

Validation: Release host build passed with no warnings/errors; 21 LightweightStyling unit tests and the targeted TypedResource selftests passed. Deliberately disabling the Thickness/FontWeight setters and FontFamily equality caused the relevant checks to fail; the restored implementation passed again. Styling documentation compiles and both API indexes match.

Existing dependency warnings in the unit-test project and unresolved documentation cref warnings remain.

Please let me know if anything else needs adjusting.

Alexandre Zollinger Chohfi (azchohfi) added a commit that referenced this pull request Oct 15, 2026
* Add REACTOR_DYM_006: flag color strings BrushHelper can't parse (#1375)

Constant color strings that BrushHelper.ParseColor doesn't recognize silently
render gray. The new ColorStringLiteralAnalyzer flags them on BrushHelper.Parse,
ResourceBuilder.Set(string, string) and the string overloads of
Background/Foreground/BorderBrush/WithBorder, with a did-you-mean:
- *FontFamily resource key -> new FontFamily(...) (only when the
  Set(string, FontFamily) overload exists, PR #1370)
- #RGB/#ARGB shorthand -> #RRGGBB/#AARRGGBB; missing '#' -> add it
- CSS/WinUI named color -> exact hex
ColorStringLiteralCodeFix applies these rewrites. The mur check
ColorStringLiteralRule mirrors it, anchored on the analyzer ID since the
mistake raises no compiler error.

BrushHelper gains an internal TryParseColor (no behavior change) so
ColorStringParityTests can lock BrushHelper and both classifier copies
together. Fixes the in-repo hits it found (AliceBlue in wct-controls, #888 in
ReactorHostControlDemo), which all rendered gray.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address pr-review findings for REACTOR_DYM_006

- Prune branches a constant condition / non-null ?? left side / constant
  switch rules out, so dead code is never reported.
- FontFamily: without the Set(string, FontFamily) overload (or inside a ?:
  branch) point at the .FontFamily(...) modifier; the fix renames a named
  color: argument to the overload's parameter.
- mur check rule now reads the rewrite from the analyzer's message instead
  of re-deriving it; drops the CLI classifier copy and gives each ?: branch
  its own suggestion.
- Tighter message wording; supported list includes grey/lightgrey.
- Tests: live-Reactor target test, dead-branch, FontFamily-in-branch,
  named-argument fix, BrushHelper built-in colors + gray fallback.
- Docs: skill row no longer recommends a non-existent overload; stale rule
  counts updated.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 1

- FontFamily suggestion escapes the value as a regular C# literal and
  includes the named-argument rename, so mur check's try: text compiles.
- ?? pruning uses proven non-null results from nested selectors.
- Switch pruning compares the pattern constant converted to the governing
  type.
- Explicit Where filters in Targets.Resolve and the code fix.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 2

Qualify the suggested type as Microsoft.UI.Xaml.Media.FontFamily so the
mur check try: text compiles without a using, and add a test that applies
each suggestion, recompiles, and re-runs the analyzer.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 3

Without a rewrite of the argument, a *FontFamily key's .FontFamily(...)
modifier advice was truncated out of mur check output. The rule now
surfaces it as the try: text; test asserts on the final formatted line.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 4

Record REACTOR_DYM_006 and its TreatWarningsAsErrors impact in the
CHANGELOG, per the changelog's contributor conventions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 5

A throw branch never yields null, so a ?? fallback after
(cond ? "red" : throw ...) is unreachable and no longer reported.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 6

Skip arguments that reach the color parameter through a user-defined
conversion: the operator's result, not the source strings, is parsed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 7

Treat any non-string or user-defined-conversion sub-expression as a
boundary while walking selector branches, not just the whole argument.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

* Address review round 8

A ?? whose left side reaches string through a user-defined conversion is
never provably non-null, so its outer fallback stays analyzed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b58aacd0-29b6-46c1-9603-b8a8b4eecbd8
@kusutori

Copy link
Copy Markdown
Contributor Author

Thanks for catching both issues! Fixed in dee803a:

  • Use a Button, which consumes ContentControlThemeFontFamily, instead of a TextBlock
  • Move the example into the styling doc app's font-family-resource snippet and reference it from the template
  • Recompile docs/guide/styling.md

The doc pipeline built the styling app and compiled the topic successfully. All 15 InlineSnippetLedgerTests also passed, including the check that rejected the previous inline example.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks kusutoriクスとり (@kusutori)! All review feedback is addressed and CI is green. LGTM.

@azchohfi
Alexandre Zollinger Chohfi (azchohfi) merged commit 4f0bf1c into microsoft:main Oct 21, 2026
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add missing ResourceBuilder.Set overloads for native styling values

2 participants