agmission/Development/server/docs/MARKDOWN_VIEWER.md
Devin Major ad7db99f07
Some checks failed
Server Tests / Mocha – Unit & Utility Tests (push) Successful in 1m29s
Server Tests / Jest – Integration Tests (push) Failing after 1m57s
all Data Export API changes until may 8 2026
2026-05-08 11:48:21 -04:00

132 lines
3.8 KiB
Markdown

# MarkdownViewerComponent
Selector: `app-markdown-viewer`
Module: `AppSharedModule` (already exported — no extra import needed)
A generic, self-contained markdown renderer. Handles parsing, heading-based section splitting, Mermaid diagrams, inline video embeds, syntax-highlighted find-in-page, and emits a table-of-contents item list for the host to render wherever it likes.
---
## Inputs
| Input | Type | Default | Description |
|---|---|---|---|
| `src` | `string` | `undefined` | URL of a remote `.md` file to fetch and render. Mutually exclusive with `markdown`. |
| `markdown` | `string` | `undefined` | Raw markdown string to render inline. Takes precedence over `src` if both are set. |
| `showFindBar` | `boolean` | `false` | Show the find-in-page bar above the content. |
---
## Outputs
| Output | Payload | Description |
|---|---|---|
| `tocItemsChange` | `{ label: string; anchorId: string }[]` | Emitted after content loads. Each item corresponds to a top-level heading in the document. Use this to render a Table of Contents outside the component. |
---
## Public Methods
| Method | Signature | Description |
|---|---|---|
| `scrollToId` | `(anchorId: string) => void` | Scrolls the content area to the element with the given id. Use in conjunction with `tocItemsChange` to implement external TOC navigation. |
---
## Usage Examples
### Render a remote file
```html
<app-markdown-viewer src="/assets/docs/readme.md"></app-markdown-viewer>
```
### Render an inline string
```html
<app-markdown-viewer [markdown]="myMarkdownString"></app-markdown-viewer>
```
### With find-in-page bar
```html
<app-markdown-viewer [markdown]="content" [showFindBar]="true"></app-markdown-viewer>
```
### With an external Table of Contents
The component emits TOC items but does **not** render a TOC sidebar itself. The host component is responsible for displaying the list and wiring up scroll navigation.
**Template:**
```html
<!-- TOC rendered by the host -->
<ul>
<li *ngFor="let item of tocItems">
<a href="#" (click)="scrollToHeading($event, item.anchorId)">{{ item.label }}</a>
</li>
</ul>
<!-- Viewer -->
<app-markdown-viewer
#viewer
[markdown]="content"
(tocItemsChange)="tocItems = $event">
</app-markdown-viewer>
```
**Component:**
```typescript
import { ViewChild } from '@angular/core';
import { MarkdownViewerComponent } from '../shared/markdown-viewer/markdown-viewer.component';
export class MyComponent {
@ViewChild(MarkdownViewerComponent) viewer?: MarkdownViewerComponent;
tocItems: { label: string; anchorId: string }[] = [];
content = '# Hello\n\nSome text.\n\n## Section Two\n\nMore text.';
scrollToHeading(event: MouseEvent, anchorId: string): void {
event.preventDefault();
this.viewer?.scrollToId(anchorId);
}
}
```
---
## Content Features
### Mermaid diagrams
Fenced code blocks with language `mermaid` are automatically rendered as SVG diagrams:
````markdown
```mermaid
graph TD
A --> B
```
````
### Inline video embeds
Use the custom `!video[title](url)` syntax to embed video files (`.mp4`, `.webm`, `.ogg`) or iframes (YouTube, Vimeo, etc.):
```markdown
!video[Demo walkthrough](https://example.com/demo.mp4)
!video[YouTube video](https://www.youtube.com/embed/abc123)
```
### Tables
Standard markdown tables are styled with borders and alternating row colours automatically.
---
## Notes
- Content is split into sections at every heading. The text before the first heading becomes an "intro" block.
- `src` and `markdown` are mutually exclusive. If both are provided, `markdown` wins.
- `scrollToId` is a no-op if the component has not yet rendered or the anchor does not exist in the current content.
- The component is part of `AppSharedModule` and does not need to be imported separately in feature modules that already import `AppSharedModule`.