Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,33 @@ All notable changes to ShellDocs land here. Format follows [Keep a Changelog](ht

## [Unreleased]

## [0.1.5-alpha] — 2026-08-22

The `shelldocs build` output is now a real static site. Previously it copied `publish/wwwroot/` 1:1 — fine on paper, useless in practice for a Blazor Server scaffold, which produces no `index.html`, no client-side runtime, nothing a static host can serve at the root URL. Deploying the output to GH Pages / Cloudflare Pages / Netlify silently returned a blank shell. Now every URL the site knows about is prerendered at build time and the framework's static assets are merged on top.

### Fixed

- **`shelldocs build` produces a fully static site deployable to GH Pages / Cloudflare Pages / Netlify without a .NET host.** Previously the CLI ran `dotnet publish` and copied `wwwroot/` verbatim — which, for a Blazor Server scaffold (what `shelldocs init` produces by default), contains only static assets and no HTML entrypoint. Visiting the deployed root returned an empty page; deep links 404'd. New flow: publish → launch the published app on a loopback ephemeral port → walk `NavigationGraph.AllUrls` to enumerate every route (visible + hidden) plus `/` → `HttpClient.GetAsync` each URL → save the rendered HTML to `<output>/<url>/index.html`. Then merge `publish/wwwroot/` (`_content/`, `_framework/blazor.web.js`, `app.css`, `favicon.png`, tokens CSS) on top. Result is a directory any dumb file host can serve; every URL is a real HTML file with content in the response body. Server scaffold unchanged — the prerender happens entirely inside `shelldocs build`.
- **`--base-href` now rewrites `<base href>` in every prerendered HTML file, not just the root `index.html`.** The pre-fix pass only touched one file, so subpath deploys (GH user-repo pages at `/repo/`) worked for the home page but broke every deep-linked doc route (assets 404'd because the deep-linked pages still had `<base href="/">`). New pass walks `<output>/**/*.html` and rewrites every occurrence.

### Added

- **`NavigationGraph.AllUrls`** — public enumeration of every indexed URL (visible + hidden). Needed by the new prerender walk so hidden pages still land in the static output (they route at runtime and would 404 on the static site otherwise). Trivial addition, no API break.
- **`PrerenderRunner`** internal helper in `ShellDocs.CLI` — encapsulates the subprocess launch + readiness poll + URL walk + file save. Kept out of `BuildCommand` so the orchestration reads linearly. Guarantees subprocess cleanup on every exit path (finally + `ProcessExit` + `CancelKeyPress`).

### Known limitations

- **URL discovery is content-folder-based, not runtime-based.** `PrerenderRunner` walks URLs via `NavigationGraphBuilder.Build(contentRoot)` — same logic the running app uses — so file-based routes are complete. Custom routes registered outside `content/` (bespoke `@page` directives) won't be prerendered and will need to be added manually. Not a regression from `0.1.4-alpha` behavior (which prerendered nothing).
- **Interactive server components at request time.** The prerendered HTML is a snapshot of the initial render; hydration on the client picks up from there via `<script src="_framework/blazor.web.js">`. Deep-linking to a page hits the static HTML; the theme toggle, search, tabs, code copy work via the shipped `shelldocs.js` on top. Full Blazor Server interactivity (SignalR-backed component state) doesn't survive the static build — but a docs site doesn't need it.

## [0.1.4-alpha] — 2026-08-22

Second dogfood batch. `0.1.3-alpha` pinned the sidebar footer to a fixed slot but only under the desktop Sidebar variant — footer still floated mid-sidebar on TopNav / mobile drawer / short-tree cases.
`0.1.3-alpha` pinned the sidebar footer to a fixed slot but only under the desktop Sidebar variant — footer still floated mid-sidebar on TopNav, mobile drawer, and short-tree cases. This release covers that plus three primitive-DX improvements.

### Fixed

- **Sidebar footer now pins to the bottom in every layout context.** The `0.1.3-alpha` fix only worked in the desktop Sidebar variant — the `flex: 1; min-height: 0` sizing that lets the nav fill its slot was scoped to `.docs-shell-sidebar .docs-sidebar-slot > nav` inside a `@media (min-width: 1024px)` block. On the TopNav variant, the mobile drawer, or any Sidebar site whose tree is shorter than the slot, the nav still collapsed to intrinsic content size and the footer (GitHub link + theme toggle) sat wherever the tree ended, mid-sidebar. Moved `flex: 1; min-height: 0` onto `.docs-sidebar` itself and made `.docs-sidebar-slot` `display: flex; flex-direction: column` in every context. Footer pins hard to the bottom regardless of variant / viewport / item count.
- **`razor:preview` fences with an unknown outer tag now render a visible error in the frame instead of falling back to a plain code block silently.** Previously `SlotExtractor.TryBuildPreviewSlot` returned `null` when the fence's first tag didn't resolve to a registered component; the fence rendered as regular fenced code with only a build-log warning. Authors chasing "why isn't my icon rendering" would hunt for a nonexistent component bug. Now the same case emits a `PreviewSlot` with `ComponentType = null` and an `Error` message; `PreviewFrame` renders a red-tinted error panel in the render region naming the unknown tag and pointing at `o.RegisterComponent<T>()` / `o.RegisterComponentsFromAssembly<TMarker>()`. Build-log warning still emitted. `PreviewSlot.ComponentType` is now nullable — technically a source-breaking change for callers pattern-matching on it, though external consumers of that type are ~none in the alpha window. [SHELLDOCS_FIXES.md #4]
- **`razor:preview` fences with an unknown outer tag now render a visible error in the frame instead of falling back to a plain code block silently.** Previously `SlotExtractor.TryBuildPreviewSlot` returned `null` when the fence's first tag didn't resolve to a registered component; the fence rendered as regular fenced code with only a build-log warning. Authors chasing "why isn't my icon rendering" would hunt for a nonexistent component bug. Now the same case emits a `PreviewSlot` with `ComponentType = null` and an `Error` message; `PreviewFrame` renders a red-tinted error panel in the render region naming the unknown tag and pointing at `o.RegisterComponent<T>()` / `o.RegisterComponentsFromAssembly<TMarker>()`. Build-log warning still emitted. `PreviewSlot.ComponentType` is now nullable — technically a source-breaking change for callers pattern-matching on it, though external consumers of that type are ~none in the alpha window.

### Added

Expand All @@ -20,30 +39,26 @@ Second dogfood batch. `0.1.3-alpha` pinned the sidebar footer to a fixed slot bu
o.RegisterComponentsFromAssembly<Marker>("ShellIcons.Icons");
```
instead of the lambda form. The `Func` overload stays for anything more complex.
- **`shelldocs init` scaffolded `Program.cs` now surfaces the `LayoutVariant` knob.** Commented-out `// o.LayoutVariant = DocsLayoutVariant.Sidebar;` line right in the `AddShellDocs(...)` block, plus the `RegisterComponentsFromAssembly` hint. First-time consumers no longer have to grep `ShellDocs.Components/Layouts/DocsLayout.razor` to discover the sidebar-variant option exists. [SHELLDOCS_FIXES.md #3]
- **`shelldocs init` scaffolded `Program.cs` now surfaces the `LayoutVariant` knob.** Commented-out `// o.LayoutVariant = DocsLayoutVariant.Sidebar;` line right in the `AddShellDocs(...)` block, plus the `RegisterComponentsFromAssembly` hint. First-time consumers no longer have to grep `ShellDocs.Components/Layouts/DocsLayout.razor` to discover the sidebar-variant option exists.

### Not fixed this batch
### Known limitations

Three items from SHELLDOCS_FIXES.md deferred; they need spec-level work rather than a patch:
Two items deferred to future releases; both need spec-level design rather than a patch:

- **#1 / #2 — `shelldocs build` produces no `index.html`, and `init`/`build` render-mode mismatch.** The scaffolded project is Server-interactive but `build` prints "publish kind: static (Blazor WASM)" and copies the resulting `wwwroot/` — which for a Server-interactive project has no `index.html`, no `_framework/dotnet.js`, no runtime blob. Output is unusable as a static site (blocks GH Pages / Cloudflare / Netlify deploys). Two viable paths (server-side prerender walk of the nav graph, or scaffold WASM Standalone by default) — either is a substantial change to `BuildCommand` and/or `InitCommand`. Design work needs to happen before this lands. Consumers workaround: `dotnet run` locally, skip `shelldocs build`.
- **#5 — Markdig mangles inline HTML wrappers between component slots in `razor:preview`.** Plain `<span style="color:…">` around a registered component tag inside a preview loses its parent-child relationship after Markdig's inline pass, because SlotExtractor lifts component tags before Markdig sees them. Documented workaround: use registered wrapper components with their own attribute props instead of raw inline HTML. Framework fix would need SlotExtractor to lift-and-preserve trivial wrappers (`<span>`, `<a>`, `<button>`) around component tags.
- **`shelldocs build` produces no `index.html`, and `init`/`build` render-mode mismatch.** The scaffolded project is Server-interactive but `build` prints "publish kind: static (Blazor WASM)" and copies the resulting `wwwroot/` — which for a Server-interactive project has no `index.html`, no `_framework/dotnet.js`, no runtime blob. Output is unusable as a static site (blocks GH Pages / Cloudflare / Netlify deploys). Two viable paths (server-side prerender walk of the nav graph, or scaffold WASM Standalone by default) — either is a substantial change to `BuildCommand` and/or `InitCommand`. Consumers workaround: `dotnet run` locally, skip `shelldocs build`.
- **Markdig mangles inline HTML wrappers between component slots in `razor:preview`.** Plain `<span style="color:…">` around a registered component tag inside a preview loses its parent-child relationship after Markdig's inline pass, because SlotExtractor lifts component tags before Markdig sees them. Workaround: use registered wrapper components with their own attribute props instead of raw inline HTML. Framework fix would need SlotExtractor to lift-and-preserve trivial wrappers (`<span>`, `<a>`, `<button>`) around component tags.

## [0.1.3-alpha] — 2026-08-12

Dogfood-driven fixes. Surfaced while writing the per-primitive / per-command / authoring pages on shelldocs.dev (30+ new sidebar entries pushed the tree past viewport height for the first time). One user-visible bug, one visual polish, both landed against the sidebar chrome.
One sidebar-chrome bug + a broader icon vocabulary for real-world consumer sites.

### Fixed

- **`.docs-sidebar` no longer pushes its footer off-screen when the tree scrolls.** In `DocsLayoutVariant.Sidebar`, once the sidebar tree grew tall enough to need internal scrolling, the footer (GitHub link + theme toggle) disappeared below the visible area of the floating sidebar card. Root cause: `DocsSidebar.razor.css` set `height: 100%` on the nav, which in a flex-column parent resolves against the parent's full content box (header + nav) instead of the remaining space, overriding the `flex: 1; min-height: 0` sizing from `DocsLayout.razor.css`. Removed the `height: 100%` and added `min-height: 0` in its place — footer now stays pinned to the bottom of the slot regardless of tree depth.

### Added

- **Broader `SidebarIcons` coverage.** Hand-curated icon map grew from ~20 entries to ~50. New titles covered: `Authoring`, `CLI` (+ `Cli` alias for auto-title-cased folder names), `Packages`, `Configuration`, `Project Structure`, `Quick Start`, `Frontmatter`, `Fenced Code`, `Razor Preview`, `Inline Component Tags`, `Navigation`, plus PascalCase and space-separated variants of every content primitive (`CardGrid`/`Card Grid`, `LinkCard`/`Link Card`, `Steps`, `FileTree`/`File Tree`, `TypeTable`/`Type Table`, `CodeGroup`, `PreviewFrame`/`Preview Frame`, `ComponentPreview`/`Component Preview`) and the four CLI command names (`shelldocs init`/`add`/`dev`/`build` + bare `Init`/`Add`/`Dev`/`Build`). Longer-term this is the argument for `ShellUI.Icons` ([SHELLUI_ICONS.md](docs/SHELLUI_ICONS.md)) — hand maps don't scale. Short-term this closes the visual gap where categories a mature consumer's site actually uses rendered without an icon while the framework's own vocabulary had one.

### Docs

- **`docs/SHELLUI_DOGFOOD_FIXES.md`** now tracked in git. Three entries logged from the shelldocs.dev writing session (the two fixes above, plus one still-open item: `TitleFromFolderName` doesn't uppercase acronyms — `cli/` → `Cli`, `api/` → `Api`. Worked around on the consumer via explicit `meta.json.title`; framework-level fix — either a built-in acronym set or a `ShellDocsOptions.KnownAcronyms` hook — still open).
- **Broader `SidebarIcons` coverage.** Hand-curated icon map grew from ~20 entries to ~50. New titles covered: `Authoring`, `CLI` (+ `Cli` alias for auto-title-cased folder names), `Packages`, `Configuration`, `Project Structure`, `Quick Start`, `Frontmatter`, `Fenced Code`, `Razor Preview`, `Inline Component Tags`, `Navigation`, plus PascalCase and space-separated variants of every content primitive (`CardGrid`/`Card Grid`, `LinkCard`/`Link Card`, `Steps`, `FileTree`/`File Tree`, `TypeTable`/`Type Table`, `CodeGroup`, `PreviewFrame`/`Preview Frame`, `ComponentPreview`/`Component Preview`) and the four CLI command names (`shelldocs init`/`add`/`dev`/`build` + bare `Init`/`Add`/`Dev`/`Build`). Closes the visual gap where categories a mature consumer's site actually uses rendered without an icon while the framework's own vocabulary had one. Longer-term a first-class icon package will replace this hand map.

## [0.1.2-alpha] — 2026-07-28

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

<!-- Package metadata (applies to any project with IsPackable=true) -->
<PropertyGroup>
<Version>0.1.4-alpha</Version>
<Version>0.1.5-alpha</Version>
<Authors>ShellUI</Authors>
Comment on lines 20 to 22
<Company>ShellUI</Company>
<Copyright>Copyright © 2026 ShellUI</Copyright>
Expand Down
Loading
Loading