docs: add a custom DocFX theme, landing page, and guides - #190
Conversation
The documentation site used the stock `default` + `modern` templates with a landing page that only included the root README. This gives it its own identity and fills the gaps in what it covers. Theme (`docfx/templates/projgraph/`) is layered on top of `default` + `modern`, overriding only Bootstrap custom properties and documented docfx selectors so a docfx upgrade shifts as little as possible underneath it. Colour is semantic: cyan marks graph structure and runnable commands, steel marks everything else. The light theme is designed rather than derived from an inversion of the dark ramp. Inter and JetBrains Mono are self-hosted to avoid a third-party request. The landing page replaces the README include. Its signature visual is the transform the tool performs: a `DbContext` on the left, the ERD it produces on the right, drawn as inline SVG so there is no layout shift and no dependency on Mermaid having loaded. The edges draw once on load, gated behind `prefers-reduced-motion`. `samples/**/*.md` was built into the site but reachable from no TOC, so the whole showcase was orphaned. It is now a Showcase section in the top nav. Three guides cover ground the package READMEs do not: onboarding, choosing between the output formats, and what to do when a diagram comes back empty. Also fixes the root README, which documented `visualize` as defaulting to tree format. It defaults to mermaid. Verified with `docfx docfx/docfx.json --warningsAsErrors` (the publish workflow's command) from a wiped `_site`/`api`: 0 warnings, 0 errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new copy-button fallback can throw due to an unguarded window.getSelection() null case, which should be fixed to avoid breaking the enhancement script.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR revamps the DocFX documentation site for ProjGraph by introducing a custom theme, a new HTML-based landing page, and new end-user guides, making the docs more discoverable and visually aligned with the project’s identity.
Changes:
- Adds a custom DocFX template layer (
templates/projgraph) with tailored CSS and small client-side enhancements (copy buttons + landing-page hero animation behavior). - Replaces the docs landing page with a purpose-built page showcasing ProjGraph’s value proposition and samples.
- Expands documentation structure with a Showcase nav entry and three new guides (getting started, output formats, troubleshooting).
File summaries
| File | Description |
|---|---|
| README.md | Corrects visualize default output format and adds an explicit tree example. |
| docfx/toc.yml | Adds top-level “Showcase” section to make samples reachable via nav. |
| docfx/templates/projgraph/public/main.js | Theme behavior hooks: copy buttons and landing-page hero edge-draw animation. |
| docfx/templates/projgraph/public/main.css | Full custom theme styling (tokens, typography, navbar, TOC, code blocks, landing page). |
| docfx/samples/toc.yml | Adds a TOC for samples to expose them in the generated docs navigation. |
| docfx/index.md | Replaces the include-based landing page with a custom landing experience and links. |
| docfx/guides/getting-started.md | New guide for installing/using CLI and MCP server. |
| docfx/guides/output-formats.md | New guide explaining mermaid vs tree vs flat and --output fencing behavior. |
| docfx/guides/troubleshooting.md | New guide mapping common errors to concrete fixes. |
| docfx/guides/toc.yml | Adds the new guides into the Guides navigation structure. |
| docfx/docfx.json | Registers new content files, the custom template, and site metadata/footer configuration. |
Review details
- Files reviewed: 11/16 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| function selectContents(node) { | ||
| const range = document.createRange() | ||
| range.selectNodeContents(node) | ||
| const selection = window.getSelection() | ||
| selection.removeAllRanges() | ||
| selection.addRange(range) | ||
| } |
There was a problem hiding this comment.
Fixed in a9d316f.
The consequence was a bit worse than the null throw itself: selectContents(code) ran before report(...) in the catch block, so a throw there would have skipped the button's feedback entirely and left it reading "Copy" as though the click had done nothing.
selectContents now returns whether it managed to select, and the catch branch always reports. When there's no selection to make, the button says "Select to copy" instead of pointing at a copy shortcut that would act on an empty selection.
Verified all three paths in a browser:
| Scenario | Button | Result |
|---|---|---|
| Clipboard permitted | Copied |
command on the clipboard |
| Clipboard refused, selection available | Press Ctrl+C |
command selected |
Clipboard refused, getSelection() returns null |
Select to copy |
reverts to Copy, no page error |
`window.getSelection()` returns null when the window has no associated document. The copy button's fallback called `removeAllRanges()` on it directly, and because that ran before `report()`, a throw there would have skipped the button's feedback entirely — leaving it reading "Copy" as though nothing had happened. `selectContents` now returns whether it managed to select. When it could not, the button says "Select to copy" rather than pointing at a copy shortcut that would act on an empty selection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Summary
The documentation site used the stock
default+moderntemplates, with a landing page that only included the root README and a footer reading "Made with DocFX." This gives it its own identity and fills the gaps in what it covers.Visual direction takes its cue from RustPlusApi and DotnetTokenKiller so the three sites read as siblings, with a palette of its own drawn from the ProjGraph icon.
What's in it
Custom theme —
docfx/templates/projgraph/Layered on top of
default+modern, overriding only Bootstrap custom properties (--bs-*) and documented docfx selectors, so a docfx upgrade shifts as little as possible underneath it. No forked template partials, no CSS build step.icon.png. Colour is semantic: cyan marks graph structure and things you can run (nodes, edges, the active TOC rail, shell code blocks); steel marks all other chrome.main.jsuses only documented extension points —defaultTheme,iconLinks,mermaid,start— and adds copy buttons with a fallback for when clipboard access is refused.Landing page
Replaces the
[!include README.md]. Its signature visual is the transform the tool actually performs: aDbContexton the left, the ERD it produces on the right — drawn as inline SVG rather than live Mermaid, so there is no layout shift and no dependency on Mermaid having loaded. The edges draw themselves once on load, gated behindprefers-reduced-motion. It is the page's only non-user-triggered motion.Showcase navigation
samples/**/*.mdwas already being built into the site but was linked from no TOC, so all nine sample pages — which already embed rendered Mermaid — were unreachable. They are now a Showcase section in the top nav.Three new guides
Covering ground the package READMEs do not: getting started, output formats (
treevsflatvsmermaid, and how--outputdecides fencing), and troubleshooting.Drive-by fixes
visualizeas defaulting to tree format. It defaults tomermaid.code.hljsships its ownrgb(30,30,30)background that outranked the theme's rule and punched a grey box out of the navy on every code block.<wbr>into headings at camelCase boundaries so long API type names can wrap. That is right for the API reference and wrong in the hero, where it split "ProjGraph" across two lines on mobile. Hiding the element removes the break opportunity; the rule is scoped so reference headings keep it.Testing
docfx docfx/docfx.json --warningsAsErrors— the same command the publish workflow runs — passes from a wiped_site/api: 0 warnings, 0 errors.Checked in a real browser at 1440px and 390px, in both light and dark:
prefers-reduced-motion: reduce, the hero graph ships fully visible rather than stuck in its hidden pre-animation state.🤖 Generated with Claude Code