feat: consumer DX : assembly scan, aliases, shelldocs add, inline-slot indent fix - #13
Merged
Merged
Conversation
…, including improved component registration and authoring templates
…ion pages, introducing template options and file handling logic
…rame components, and update TypeTable styling for consistency
…nd assembly scanning for automatic registration of public components
…ect formatting in Markdig
…ine documentation authoring
…mponent alias registration to ensure functionality and correctness
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bundles four consumer-DX wins into one branch. The pitch: get a ShellUI docs site from empty to authoring in one line of Program.cs and one CLI command.
1. Assembly-scan registration (
ShellDocs.Components)Kills the "hand-type
RegisterComponent<T>()for every ShellUI component" tax:New API on
ShellDocsOptions:RegisterComponentsFromAssembly<TMarker>(Func<Type, bool>? filter = null)— scans the marker's assembly for public, concrete, non-genericComponentBasesubclasses and registers each. HandlesReflectionTypeLoadExceptiongracefully.RegisterComponentsFromAssembly(Assembly, Func<Type, bool>? filter = null)— explicit form with a filter predicate:RegisterComponent(Type)— runtime overload alongside the existing generic form; validatesComponentBaseassignability with a clearArgumentException.[ShellDocsIgnore]attribute — opt-out marker for public components that shouldn't be reachable from markdown authoring.Dogfooded on ourselves:
AddShellDocsused to register each shipped primitive with an explicit thirteen-line block; now it's:A new primitive dropped into
Content/auto-appears in the registry without editingServiceCollectionExtensions.cs.MarkdownContentandPreviewFrameopt out via@attribute [ShellDocsIgnore].2. Alias overloads (
ShellDocs.Components)For consumers who want a component registered under a different markdown-facing tag (e.g.
<Btn>rendersShellUI.Button):RegisterComponent<T>(string tagName)andRegisterComponent(Type, string tagName)— writes to a newComponentAliasesdictionary onShellDocsOptions.BuildTypeRegistryconsultsComponentAliasesbefore falling back totype.Name. Last-write-wins if the same type is registered under multiple aliases.ArgumentException.3.
shelldocs add <template> <name>CLI (ShellDocs.Templates+ShellDocs.CLI)Scaffolds a starter
.mdpage intocontent/. Three templates:Slugifies PascalCase inputs (
MyBigCard→my-big-card.md) and TitleCases kebab inputs (getting-started→ "Getting Started"). Refuses to overwrite unless--force. Fails clean if nocontent/directory is found.PageTemplatesstatic class inShellDocs.Templatesholds the three template bodies — same access pattern as the existingStarterPageTemplate.Program.cs's placeholdernewcommand stub was repurposed into the wired-upadd.4. Inline-slot indent fix (
ShellDocs.Markdown)SlotExtractor.ReplaceComponentTagsno longer.Trim()s the raw child content of inline component tags. The Trim was stripping the first line's indent and defeatingSlotRenderer.Dedent— Markdig then re-interpreted the remaining 4-space-indented lines as an indented code block. Symptom was the same "literal<pre>around placeholder divs" bug that had already been fixed forrazor:previewfences; the inline-tag code path was still hitting it. One-line change + prose comment explaining why.5. TypeTable polish
required→Required;text-transform: uppercaseand matching letter-spacing dropped; font-size bumped 0.68rem → 0.72rem to compensate for lowercase reading smallertext-transform: uppercase+ letter-spacing; font-size 0.75rem → 0.78rem. Headers now render as "Prop / Type / Default / Description" instead of "PROP / TYPE / DEFAULT / DESCRIPTION"Roadmap updates
feat/content-primitivesandfeat/api-reference-primitivesshipped with the actual delivered scopefeat/consumer-registration-dx) as a shipped Phase 2 entry with the multi-package touch listfeat/animation-polishand the0.2.0-alphaNuGet cutTest plan
dotnet build shelldocs.slnx— clean, 0 warnings, 0 errorsdotnet test shelldocs.slnx— 119 / 119 passing (+12 new: 8AssemblyScanTests, 4ComponentAliasTests, 8AddCommandTestsvia reflection to match the existingInitCommandTestspattern; net new tests = 20 minus the 8 assembly-scan already counted in the last PR draft = 12)dotnet run --project src/ShellDocs.CLI -- add component MyBigCard --dir <sandbox>writescontent/docs/components/my-big-card.mdwith correct slug, PascalCasetitle, and template bodycallout,card,steps,filetree,code-group,type-table,component-preview) renders with zero errors — proves neither the dogfooded assembly scan nor the SlotExtractor Trim fix regressed anythingNew test coverage
AssemblyScanTests(8):ComponentBasetypes[ShellDocsIgnore]TypeRegistryend-to-endRegisterComponent(Type)overload rejects non-ComponentBaseComponentAliasTests(4):AddCommandTests(8):componentwrites tocontent/docs/components/with slugged filenameguidewrites tocontent/docs/guides/with title-cased frontmatter titlepagewrites tocontent/docs/with blank body (no razor:preview)content/dir returns non-zero--forcefails--forceoverwrites