@ngrdt/docs
v0.3.1
Published
Documentation framework for the ngrdt libraries — the in-house replacement for ng-doc. Pages are plain markdown, everything component-related (inputs, outputs, methods, CSS tokens, playgrounds, API tables) is **generated from the TypeScript source** by a
Downloads
578
Readme
@ngrdt/docs
Documentation framework for the ngrdt libraries — the in-house replacement for ng-doc. Pages are
plain markdown, everything component-related (inputs, outputs, methods, CSS tokens, playgrounds,
API tables) is generated from the TypeScript source by a prebuild analyzer. The app builds
with the standard @angular/build:application executor; there is no custom builder.
The live documentation is apps/rdt-docs-next (npx nx serve rdt-docs-next). A full authoring
guide with rendered examples lives inside the docs themselves under Getting started → Writing
docs.
How it works
docs/**/*.md ──► prebuild (tsx, ~1.5 s) ──► generated manifest + content assets + component meta
│ │
│ TS analyzer (tsconfig program) ▼
└─ inputs/outputs/methods/CSS tokens ──► playgrounds, API tablesThe prebuild is a plain Node script wired as a cached Nx target (rdt-docs-next:prebuild,
build depends on it). Watch mode re-runs on markdown changes and reuses the TS analysis unless
a .ts file changed.
Authoring a page
Pages follow a folder convention under the app's docs/ root — no per-page TypeScript:
docs/components/category.json { "title": "Components", "order": 3, "expandable": true }
docs/components/tooltip/index.md the page (frontmatter + markdown)
docs/components/tooltip/demo/… demo components (plain Angular components)Frontmatter keys: title, order, keywords (search boost), and for tab variants a sibling
folder with its own .md using route/title (see existing rdt-gov-* pages).
A complete component page can be one directive:
---
title: Tooltip
order: 12
---
:::component RdtGovTooltipComponent playgroundDirectives
| Directive | Effect |
|---|---|
| :::component <Class> [playground] | Expands to description + optional Playground + API sections |
| :::description <Class> | Lead paragraph from the class JSDoc |
| :::playground <Class> | Live component + auto-discovered controls, code snippet, theming editor, shareable URL state |
| :::api <Class> | Input/Output/Method/CSS-token tables (JSDoc descriptions, @deprecated badges) |
| :::demo <Class> [files="a.ts,a.html"] | Live demo with extracted source tabs |
| :::code <path>[#region] | Embeds a real source file (or // #region section) as a code block |
| :::include <path> | Inlines another markdown file at prebuild |
Directives inside fenced code blocks stay literal — safe to show as examples.
Code fences support a file-name label: ```ts fileName="my-page.component.ts".
What the analyzer extracts
For every class referenced by :::api/:::playground (any class exported from a workspace
library barrel works — the analyzer adds all tsconfig-path roots):
- inputs —
input(),input.required(),model()incl. inherited ones, aliases, transforms, literal-union select options, statically resolvable defaults, JSDoc descriptions - outputs —
output(),outputFromObservable(), plus implicit<model>Change - methods — public, JSDoc-documented (lifecycle and private members are skipped)
- CSS tokens —
--rdt-*custom properties from the component scss (styleUrl + sibling files) - selector and class description (JSDoc);
@deprecatedtags become badges
Writing JSDoc on the component/inputs is all it takes to fill descriptions everywhere (API tables, description paragraphs).
Playground registry (app side)
export const DOCS_PLAYGROUNDS: RdtDocsPlaygroundRegistry = {
RdtGovButtonComponent: {
loadComponent: () => Promise.resolve(RdtGovButtonComponent),
controlOverrides: { label: { defaultValue: 'Gov Button' } },
},
MyWrapperComponent: {
loadComponent: () => import('./wrapper').then((m) => m.MyWrapperComponent),
hideSnippet: true, // wrapper selector would mislead consumers
themingTokensFrom: 'RdtTableComponent', // whose CSS tokens power the theming editor
staticInputs: { config: { /* fixed, hidden from the panel */ } },
hideInherited: true,
},
};App setup
provideRdtDocs({
manifest: RDT_DOCS_MANIFEST, // generated
componentMeta: RDT_DOCS_COMPONENT_META, // generated
demos: DOCS_DEMOS,
playgrounds: DOCS_PLAYGROUNDS,
editUrl: (sourcePath) => `…repo url…?path=/docs/${sourcePath}`, // "Edit this page"
}),
provideRouter([...ownRoutes, ...buildRdtDocsRoutes(RDT_DOCS_MANIFEST)], withInMemoryScrolling(...)),Prebuild CLI (see apps/rdt-docs-next/project.json for the wired target):
tsx @ngrdt/docs/prebuild/main.ts
--root <docs-dir> --out <content-dir> --manifest <manifest.ts>
--tsconfig <app tsconfig> --component-meta <meta.ts>
[--strict-links] fail the build on broken internal links (watch mode only warns)
[--watch]Build assets must serve the generated content (docs-content/) and llms.txt; the shell, search
(⌘K), theme toggle, TOC rail, mobile drawer and landing patterns are shown in apps/rdt-docs-next.
Peer dependencies
marked, shiki (+ @shikijs/langs, @shikijs/themes), minisearch, @ngrdt/tabs; the
prebuild additionally uses typescript and chokidar (dev).
