Publish a machine-readable index of the Toolkit samples #878
Jaylyn-Barbee
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
The problem
Anything outside this repository that wants to show a Toolkit sample has to scrape the repository and guess at its layout. The samples live as
[!SAMPLE]markers incomponents/*/samples/*.md, resolved against[ToolkitSample…]-attributed classes and their.xaml/.xaml.cspairs. That indirection is good for the sample app and hostile to everyone else — documentation sites, search, and AI coding assistants all end up reimplementing a partial version of the same resolution, and each one drifts independently as the samples change.The practical result today is that assistants asked for, say, a
SettingsCardsnippet tend to produce markup that looks plausible and does not compile: invented attributes, missingxmlnsdeclarations, or the sample app'sx:Classand option-binding scaffolding pasted verbatim into a page the user is actually writing.The idea
Publish the samples as a generated, machine-readable file in the repository —
catalog/toolkit-samples.json— and keep it honest with CI.One entry per documentation page, one sample per
[!SAMPLE]marker, in the order the page presents them. Each sample carries markup that is meant to be pasted: the<Page>wrapper andx:Classremoved, design-time namespaces dropped,<Page.Resources>moved onto the surviving element so referenced keys stay in scope, and the sample app's option bindings replaced by the literal value the gallery opens with. Thexmlnsdeclarations the snippet actually uses are listed alongside it. Code-behind is reduced to the handlers the markup calls and the types it binds to, with the license header, page class andInitializeComponentscaffolding stripped.The rule throughout is that the environment changes and the sample never does. A sample whose markup cannot be made pasteable is reported and left out rather than published broken, and anything withheld is named rather than disappearing quietly.
Repository-specific fields sit under a
toolkitobject so the surrounding shape stays portable if another sample source ever wants to publish the same way.{ "schemaVersion": 1, "source": "toolkit", "controls": [ { "id": "settingscard", "name": "SettingsCard", "nugetPackage": "CommunityToolkit.WinUI.Controls.SettingsControls", "curatedKeywords": ["SettingsCard", "Control", "Layout", "Settings"], "samples": [ { "header": "SettingsCard", "xaml": "<StackPanel Spacing=\"4\">…</StackPanel>", "xmlnsImports": ["xmlns:controls=\"using:CommunityToolkit.WinUI.Controls\""], "toolkit": { "sampleId": "SettingsCardSample", "sourcePath": "components/…" } } ] } ] }Why generate it in-repo rather than scrape it outside
Because drift is then caught in the pull request that causes it, by the people who have the context to fix it, instead of silently degrading someone else's index weeks later. A consumer fetching one committed file also needs no knowledge of the layout at all, so changing how samples are organised stops being a breaking change for everyone downstream.
The exporter reads the samples as text rather than building them, so the check runs on
ubuntu-latestwith no workloads and reports a stale index in well under a minute — it does not wait on the build matrix.Current state
I have this working against today's
mainand would like feedback before opening a PR. It is a .NET 9 console tool undertools/, roughly 3,000 lines with 86 tests, and it indexes 72 entries and 125 samples. Pages documenting APIs with no markup — most ofExtensionsandHelpers— are included with an emptysamplesarray so the index covers the whole component surface, not just the parts with XAML.Branch: https://github.com/Jaylyn-Barbee/Windows/tree/sample-index-exporter
What I would like input on
catalog/the right home, and is a required CI check acceptable, given it means a sample change that forgets to regenerate fails the build?schemaVersion: 1.Happy to open it as a PR, split it up, or drop it if the direction is wrong.
All reactions