feat: onboard React Flow documentation views

This commit is contained in:
2026-08-14 11:09:35 +00:00
parent b25b1f9842
commit 978a10a189
3 changed files with 430 additions and 4 deletions
+9 -4
View File
@@ -8,18 +8,18 @@ description: >
admonitions, editing docusaurus.config.ts, applying voice and inclusive-language standards, admonitions, editing docusaurus.config.ts, applying voice and inclusive-language standards,
or setting up deployment to Vercel, Netlify, GitHub Pages, or Cloudflare Pages. Triggers on or setting up deployment to Vercel, Netlify, GitHub Pages, or Cloudflare Pages. Triggers on
docs/, blog/, docusaurus.config, sidebars.ts, .mdx files, or any request to write, improve, docs/, blog/, docusaurus.config, sidebars.ts, .mdx files, or any request to write, improve,
build a local YAML data database for React/MDX views, render editable Draw.io sources with build a local YAML data database for React/MDX views, create React Flow roadmaps or dependency
docusaurus-plugin-drawio, or restructure documentation — even when the user only says "write docs", "document this", maps, render editable Draw.io sources with docusaurus-plugin-drawio, or restructure documentation — even when the user only says "write docs", "document this",
or "the docs are a mess". Asks who the reader is and what they should be able to DO before or "the docs are a mess". Asks who the reader is and what they should be able to DO before
writing, because the answer decides the structure. writing, because the answer decides the structure.
license: MIT license: MIT
metadata: metadata:
author: workspace-skills-code-agent author: workspace-skills-code-agent
version: "1.2" version: "1.3"
spec: agentskills.io/specification spec: agentskills.io/specification
framework: Diátaxis framework: Diátaxis
hermes: hermes:
tags: [docusaurus, documentation, diataxis, drawio, mdx] tags: [docusaurus, documentation, diataxis, drawio, mdx, react-flow]
related_skills: [drawio-main] related_skills: [drawio-main]
compatibility: Designed for Docusaurus v3. Works with Cline, Claude Code, GitHub Copilot, OpenAI Codex, and other compatible agent environments compatibility: Designed for Docusaurus v3. Works with Cline, Claude Code, GitHub Copilot, OpenAI Codex, and other compatible agent environments
--- ---
@@ -134,6 +134,10 @@ Use these replacements. This isn't optional:
When Epics, Features, Tasks, requirements, or architectural decisions must feed several documentation views, keep the authoritative records in a local `.yml`-only data tree and load them during the Docusaurus build. Requirements must use separate functional and non-functional folders, and architectural decisions must use the exact `data/architecture-decisions/` folder. Do not duplicate records inside MDX. Follow [references/local-yaml-data-database.md](references/local-yaml-data-database.md) for record schemas, stable IDs, canonical relationships, generated indexes, validation, React hooks/components, MDX composition, and maintenance commands. When Epics, Features, Tasks, requirements, or architectural decisions must feed several documentation views, keep the authoritative records in a local `.yml`-only data tree and load them during the Docusaurus build. Requirements must use separate functional and non-functional folders, and architectural decisions must use the exact `data/architecture-decisions/` folder. Do not duplicate records inside MDX. Follow [references/local-yaml-data-database.md](references/local-yaml-data-database.md) for record schemas, stable IDs, canonical relationships, generated indexes, validation, React hooks/components, MDX composition, and maintenance commands.
### React Flow roadmaps and dependency maps
Use `@xyflow/react` when validated documentation data needs an interactive roadmap, Gantt-like timeline, Feature dependency graph, Requirement-to-Feature traceability map, or architectural decision-to-Feature map. React Flow is the renderer, not the source database or an automatic layout engine. Follow [references/react-flow-visualizations.md](references/react-flow-visualizations.md) for Docusaurus BrowserOnly integration, deterministic Gantt positioning, Dagre/ELK layout choices, source-YAML adapters, read-only interaction, accessibility, sharp styling, semantic table fallbacks, testing, and browser verification.
### Draw.io source diagrams ### Draw.io source diagrams
When a page needs a Draw.io diagram, keep the editable `.drawio` XML in the documentation repository and render that source directly with `docusaurus-plugin-drawio`. Load `drawio-main` to author or change the diagram, then follow [references/drawio-source-diagrams.md](references/drawio-source-diagrams.md) to install the plugin with pnpm, register it, consume the source from MDX with `@theme/Drawio` and `!!raw-loader!`, select multi-page diagrams, and verify the production build and browser rendering. An exported PNG/SVG alone is not an onboarded source diagram. When a page needs a Draw.io diagram, keep the editable `.drawio` XML in the documentation repository and render that source directly with `docusaurus-plugin-drawio`. Load `drawio-main` to author or change the diagram, then follow [references/drawio-source-diagrams.md](references/drawio-source-diagrams.md) to install the plugin with pnpm, register it, consume the source from MDX with `@theme/Drawio` and `!!raw-loader!`, select multi-page diagrams, and verify the production build and browser rendering. An exported PNG/SVG alone is not an onboarded source diagram.
@@ -186,6 +190,7 @@ Load the one that matches the task. Don't read all four.
| Write or edit prose, headings, lists, or code examples | [references/writing-guide.md](references/writing-guide.md) — voice, words to cut, inclusive language, pre-publish checklist | | Write or edit prose, headings, lists, or code examples | [references/writing-guide.md](references/writing-guide.md) — voice, words to cut, inclusive language, pre-publish checklist |
| Touch `docusaurus.config.ts` | [references/config-reference.md](references/config-reference.md) — the options that matter, sensible defaults, config anti-patterns | | Touch `docusaurus.config.ts` | [references/config-reference.md](references/config-reference.md) — the options that matter, sensible defaults, config anti-patterns |
| Build or maintain a local YAML database that feeds React components and MDX | [references/local-yaml-data-database.md](references/local-yaml-data-database.md) — dedicated entity folders, `.yml` schemas, indexes, relationships, build-time loading, typed hooks, and validation | | Build or maintain a local YAML database that feeds React components and MDX | [references/local-yaml-data-database.md](references/local-yaml-data-database.md) — dedicated entity folders, `.yml` schemas, indexes, relationships, build-time loading, typed hooks, and validation |
| Build a React Flow roadmap, Gantt-like view, or dependency/traceability map | [references/react-flow-visualizations.md](references/react-flow-visualizations.md) — `@xyflow/react`, Docusaurus client boundaries, YAML adapters, layouts, accessibility, fallbacks, and verification |
| Onboard or render an editable `.drawio` source | [references/drawio-source-diagrams.md](references/drawio-source-diagrams.md) — pnpm install, plugin registration, MDX raw-source import, viewer options, and verification | | Onboard or render an editable `.drawio` source | [references/drawio-source-diagrams.md](references/drawio-source-diagrams.md) — pnpm install, plugin registration, MDX raw-source import, viewer options, and verification |
| Repair a docs section that builds but violates a required hierarchy or content contract | [references/architecture-ia-remediation.md](references/architecture-ia-remediation.md) — RED-first structure validation, approval-safe scaffolding, link pitfalls, browser checks, and remote PR/CI readback | | Repair a docs section that builds but violates a required hierarchy or content contract | [references/architecture-ia-remediation.md](references/architecture-ia-remediation.md) — RED-first structure validation, approval-safe scaffolding, link pitfalls, browser checks, and remote PR/CI readback |
| Ship the site, or debug a failing build | [references/deployment.md](references/deployment.md) — Vercel, Netlify, GitHub Pages, Cloudflare, and common failures | | Ship the site, or debug a failing build | [references/deployment.md](references/deployment.md) — Vercel, Netlify, GitHub Pages, Cloudflare, and common failures |
+12
View File
@@ -105,12 +105,21 @@ id: feature-001
title: Display project lifecycle state title: Display project lifecycle state
status: in-progress status: in-progress
epic_id: epic-001 epic_id: epic-001
depends_on_feature_ids:
- feature-000
roadmap:
start: 2026-08-01
end: 2026-08-21
lane: portal
progress: 60
summary: > summary: >
Display the current lifecycle state and supporting evidence. Display the current lifecycle state and supporting evidence.
owners: owners:
- root-at-skic - root-at-skic
``` ```
`depends_on_feature_ids` is the canonical Feature dependency field. `roadmap` is optional unless the documentation exposes a date-based roadmap. When present, validate ISO dates, require `end` not to precede `start`, require a stable lane, and constrain `progress` to 0–100. React Flow adapters may derive dependency edges and Gantt-like positions from these fields; TSX and MDX must not maintain separate schedules or dependency lists.
### Task ### Task
A Task belongs to one Feature. The Task owns that relationship through `feature_id`. A Task belongs to one Feature. The Task owns that relationship through `feature_id`.
@@ -267,6 +276,8 @@ Validation must fail for:
- an unknown entity type, status, or requirement category; - an unknown entity type, status, or requirement category;
- a required field with an empty value; - a required field with an empty value;
- a dangling `epic_id`, `feature_id`, or entry in `feature_ids`; - a dangling `epic_id`, `feature_id`, or entry in `feature_ids`;
- a dangling entry in `depends_on_feature_ids`;
- an invalid roadmap date, reversed date range, missing lane, or progress outside 0–100;
- an index entry whose record is missing; - an index entry whose record is missing;
- a record missing from its collection index; - a record missing from its collection index;
- a stale relationship index; - a stale relationship index;
@@ -386,6 +397,7 @@ For schema evolution, increment `schema_version`, migrate all records and indexe
- [ ] Every entity has one stable-ID record file. - [ ] Every entity has one stable-ID record file.
- [ ] Every leaf collection has a deterministic `index.yml`. - [ ] Every leaf collection has a deterministic `index.yml`.
- [ ] Canonical relationship fields implement Epic → Feature → Task and n:m mappings to requirements and architectural decisions. - [ ] Canonical relationship fields implement Epic → Feature → Task and n:m mappings to requirements and architectural decisions.
- [ ] Feature dependencies and optional roadmap scheduling remain in source YAML and pass referential and date-range validation.
- [ ] Reverse indexes are generated, committed, and stale-index checked. - [ ] Reverse indexes are generated, committed, and stale-index checked.
- [ ] Referential validation rejects duplicate and dangling IDs. - [ ] Referential validation rejects duplicate and dangling IDs.
- [ ] Docusaurus loads data at build time. - [ ] Docusaurus loads data at build time.
+409
View File
@@ -0,0 +1,409 @@
# React Flow Documentation Visualizations
Use [React Flow](https://reactflow.dev/) when structured documentation data needs an interactive spatial view: roadmaps, Gantt-like timelines, dependency graphs, or traceability maps between Features, requirements, and architectural decisions. React Flow is a renderer and interaction layer, not the authoritative data store and not a built-in layout engine.
This capability assumes the local YAML data pattern in [local-yaml-data-database.md](local-yaml-data-database.md). Build nodes and edges from validated source YAML records. Never maintain a second copy of roadmap or relationship data inside TSX or MDX.
## Appropriate uses
Use React Flow for:
- a roadmap organized by Epic, lane, status, release, or date;
- a Gantt-like roadmap where time determines horizontal position and lane determines vertical position;
- Feature-to-Feature dependencies;
- Requirement-to-Feature n:m traceability;
- architectural decision-to-Feature n:m traceability;
- a combined, filterable delivery or architecture dependency map.
Do not use React Flow for ordinary prose, small static tables, or a linear list with no useful spatial relationship. Keep a semantic table fallback for every visualization so the information remains searchable, printable, and accessible without client-side JavaScript.
## Official baseline
Use the current package name documented by React Flow:
```text
pnpm add @xyflow/react
```
Import the required base stylesheet once in the visualization component or shared theme entry:
```ts
import '@xyflow/react/dist/style.css';
```
Relevant official guidance:
- [Quick Start](https://reactflow.dev/learn)
- [Layouting overview](https://reactflow.dev/learn/layouting/layouting)
- [Accessibility](https://reactflow.dev/learn/advanced-use/accessibility)
- [Server-side rendering](https://reactflow.dev/learn/advanced-use/ssr-ssg-configuration)
- [Testing](https://reactflow.dev/learn/advanced-use/testing)
React Flow does not provide one automatic graph layout. Its official layouting guide describes external options including Dagre, D3, and ELK. Choose and document the layout deliberately.
## Component boundary
Keep data loading, graph adaptation, layout, and rendering separate:
```text
data/**/*.yml
↓ build-time validation
DocumentationDatabase
↓ pure adapter
GraphModel { nodes, edges, fallbackRows, legend }
↓ pure layout
PositionedGraphModel
↓ React component
RoadmapFlow | DependencyMap
↓ MDX composition
Documentation page
```
Recommended source structure:
```text
src/components/documentation-data/
├── react-flow/
│ ├── DocumentationFlow.tsx
│ ├── RoadmapFlow.tsx
│ ├── DependencyMap.tsx
│ ├── nodes/
│ │ ├── FeatureNode.tsx
│ │ ├── RequirementNode.tsx
│ │ └── ArchitectureDecisionNode.tsx
│ ├── adapters/
│ │ ├── roadmapGraph.ts
│ │ ├── featureDependencyGraph.ts
│ │ ├── requirementFeatureGraph.ts
│ │ └── decisionFeatureGraph.ts
│ ├── layout/
│ │ ├── ganttLayout.ts
│ │ └── dependencyLayout.ts
│ └── DocumentationFlow.module.css
└── fallbacks/
├── RoadmapTable.tsx
└── TraceabilityTable.tsx
```
Adapters and layout functions must be pure TypeScript functions. Test them without a browser. React components receive already validated records or a typed graph model; they do not parse files.
## Docusaurus client boundary
React Flow 12 supports server rendering when node dimensions and handle positions are supplied. That is an advanced path. For normal interactive Docusaurus documentation, use Docusaurus `BrowserOnly` to avoid hydration differences and browser-global failures:
```tsx
import BrowserOnly from '@docusaurus/BrowserOnly';
import type {Props} from './DependencyMap';
export default function DependencyMapClient(props: Props) {
return (
<BrowserOnly fallback={<div>Loading dependency map…</div>}>
{() => {
const DependencyMap = require('./DependencyMap').default;
return <DependencyMap {...props} />;
}}
</BrowserOnly>
);
}
```
Use `@docusaurus/BrowserOnly`, not an unguarded `window` check scattered through components. If server-rendered graph HTML is an explicit requirement, follow the official React Flow 12 SSR guidance and provide deterministic node `width` and `height`, handle positions, and initial viewport data.
## Required canvas sizing
React Flow requires a parent with explicit dimensions. Never rely on content height:
```css
.canvas {
width: 100%;
height: min(72vh, 760px);
min-height: 420px;
border: 1px solid var(--ifm-color-emphasis-300);
border-radius: 0;
}
:global(.react-flow__node),
:global(.react-flow__controls-button),
:global(.react-flow__minimap) {
border-radius: 0;
}
```
Use sharp edges throughout. Do not introduce pill nodes, rounded cards, rounded controls, or rounded filter inputs.
## Shared read-only renderer
Documentation views are read-only unless an editing workflow is separately approved. Disable accidental graph mutation:
```tsx
import {
Background,
Controls,
MiniMap,
ReactFlow,
ReactFlowProvider,
type Edge,
type Node,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
export function DocumentationFlow({nodes, edges}: {
nodes: Node[];
edges: Edge[];
}) {
return (
<div className={styles.canvas} aria-label="Documentation dependency map">
<ReactFlowProvider>
<ReactFlow
nodes={nodes}
edges={edges}
fitView
nodesDraggable={false}
nodesConnectable={false}
deleteKeyCode={null}
nodesFocusable
edgesFocusable
disableKeyboardA11y={false}
minZoom={0.35}
maxZoom={1.8}
proOptions={{hideAttribution: false}}
>
<Controls showInteractive={false} />
<MiniMap pannable zoomable />
<Background />
</ReactFlow>
</ReactFlowProvider>
</div>
);
}
```
Keep attribution behavior compliant with the installed package's license and React Flow terms. Do not hide attribution merely for visual preference.
## Roadmap and Gantt-like layout
React Flow is not a dedicated Gantt package. Implement a Gantt-like roadmap as a deterministic node layout over validated scheduling fields.
Recommended Feature source fields:
```yaml
id: feature-001
title: Display project lifecycle state
epic_id: epic-001
status: in-progress
depends_on_feature_ids:
- feature-000
roadmap:
start: 2026-08-01
end: 2026-08-21
lane: portal
progress: 60
```
Layout rules:
1. Parse dates in one declared timezone and reject invalid ranges.
2. Compute `x` from `start` relative to the roadmap's minimum date.
3. Compute node width from the duration between `start` and `end`.
4. Compute `y` from the stable lane order in data or configuration.
5. Draw Feature dependency edges from `depends_on_feature_ids`.
6. Render release or milestone markers as non-connectable custom nodes.
7. Preserve a consistent time scale while zooming; include a visible date-axis component outside the graph viewport.
8. Provide filters for Epic, status, lane, release, and owner without mutating source data.
9. Provide a table fallback ordered by lane, start date, end date, and stable Feature ID.
Do not let dragging persist a new schedule. A documentation reader moving a node is not a data edit. If manual positioning is required for a non-time-based roadmap, store approved coordinates in source YAML and validate them.
For a roadmap without dates, use a phase or status-column layout. Keep phases in source data and calculate positions deterministically. Do not infer ordering from file enumeration.
## Dependency layouts
### Feature dependencies
Build one node per Feature and one directed edge per `depends_on_feature_ids` entry. Reject missing Feature IDs. Detect cycles and either fail validation for a declared DAG or render cycles with an explicit warning when cyclic relationships are valid domain data.
For ordinary directed acyclic Feature graphs, use Dagre:
```text
pnpm add @dagrejs/dagre
```
Dagre is appropriate for a compact, deterministic directed layout. Set node dimensions before layout and map Dagre's center-based coordinates to React Flow positions.
### Complex or grouped dependencies
For larger maps with nested Epics, compound nodes, multiple ports, or stronger edge-routing requirements, use ELK:
```text
pnpm add elkjs
```
ELK layout is asynchronous. Resolve it before rendering the final graph and show a stable loading state. Do not run a new layout on every React render.
### Requirement-to-Feature traceability
Create typed nodes and edges from canonical requirement `feature_ids`:
```text
Functional Requirement ── satisfies/constrains ──> Feature
Non-functional Requirement ── constrains ──> Feature
```
Use distinct node types, edge styles, labels, and a visible legend. Filters must distinguish functional and non-functional requirements. Do not encode meaning only with color.
### Architectural decision-to-Feature traceability
Create typed nodes and edges from canonical architectural decision `feature_ids`:
```text
Architectural Decision ── governs/affects ──> Feature
```
Display decision status and link each node to its canonical documentation route. A superseded decision remains traceable but must be visually and textually identified as superseded.
### Combined maps
A combined map may include Features, requirements, and architectural decisions, but it must start with a constrained default scope. Large all-record graphs become unreadable and expensive. Require one or more of:
- selected Epic;
- selected Feature;
- selected requirement type;
- selected decision status;
- bounded dependency depth;
- search result or explicit ID list.
Apply filtering before layout so hidden nodes do not consume space.
## Adapter contract
A graph adapter should return all rendering and fallback information from one source:
```ts
export type DocumentationGraph = {
nodes: Node<DocumentationNodeData>[];
edges: Edge<DocumentationEdgeData>[];
fallbackRows: TraceabilityRow[];
legend: LegendItem[];
warnings: GraphWarning[];
};
export function requirementFeatureGraph(
database: DocumentationDatabase,
filter: RequirementFeatureFilter,
): DocumentationGraph;
```
Requirements for every adapter:
- stable node IDs equal stable database IDs;
- stable edge IDs derived from source type, source ID, relation, and target ID;
- no random coordinates or IDs;
- no filesystem access;
- no mutation of database records;
- explicit behavior for missing, filtered, superseded, or cyclic records;
- table fallback rows derived in the same function as nodes and edges.
## MDX composition
MDX chooses the view and scope. It does not define nodes or edges:
```mdx
---
title: "Explore Feature dependencies"
description: "Inspect Feature dependencies and related requirements."
---
import DependencyMapClient from '@site/src/components/documentation-data/react-flow/DependencyMapClient';
import TraceabilityTable from '@site/src/components/documentation-data/fallbacks/TraceabilityTable';
<DependencyMapClient
mode="feature-requirements"
epicId="epic-001"
/>
<TraceabilityTable
mode="feature-requirements"
epicId="epic-001"
/>
```
The map and table must consume the same adapter output or the same normalized selector so they cannot disagree.
## Accessibility
React Flow provides keyboard and screen-reader support. Preserve it:
- keep `nodesFocusable` and `edgesFocusable` enabled;
- keep `disableKeyboardA11y={false}`;
- provide meaningful `ariaLabel` values for custom nodes and edges;
- ensure custom node links and controls have visible focus states;
- provide text labels in addition to colors and line styles;
- provide a legend that explains node types, statuses, and edge meanings;
- provide an adjacent semantic table fallback with the same filtered records;
- preserve keyboard access to filters, fit-view controls, and linked detail pages;
- test at 200% zoom and in both light and dark themes.
Read-only means mutation is disabled, not navigation or focus.
## Performance
- Memoize node types outside React components.
- Build graph data with pure selectors and memoize by database revision and filter state.
- Filter before layout.
- Avoid recreating nodes and edges on every render.
- Do not render the full database by default.
- Use bounded dependency depth for large graphs.
- Lazy-load the BrowserOnly visualization component.
- Run asynchronous ELK layout only when the relevant graph input changes.
- Measure browser interaction with representative production-size data, not only two-node examples.
## Testing and verification
Test pure transformation and layout behavior first:
- scheduling dates produce stable Gantt `x`, width, and lane `y` values;
- Feature dependencies produce the expected directed edges;
- Requirement and architectural decision n:m mappings produce complete edges;
- filters remove nodes before layout;
- dangling IDs fail validation before graph construction;
- stable inputs produce byte-equivalent graph IDs and coordinates;
- fallback table rows represent the same relationships as graph edges;
- cycles follow the declared policy.
Then test React behavior:
- the BrowserOnly fallback renders during static generation;
- the canvas mounts with explicit width and height;
- nodes and edges are keyboard focusable;
- graph mutation is disabled;
- filters, detail links, fit view, pan, and zoom work;
- missing and empty datasets render useful states;
- table fallback remains usable without the graph.
Required delivery checks:
```text
pnpm data:validate
pnpm data:check
pnpm test
pnpm typecheck
pnpm build
```
After the production build, exercise each affected page in a real browser. Verify light and dark themes, desktop and narrow widths, keyboard navigation, labels, filters, links, pan/zoom, empty states, and the table fallback. Then verify the exact Gitea Actions SHA and deployed route.
## Acceptance checklist
- [ ] `@xyflow/react` and its base stylesheet are installed and imported.
- [ ] React Flow receives validated build-time data from source YAML through a pure adapter.
- [ ] Roadmap scheduling and Feature dependencies are stored in YAML, not TSX or MDX.
- [ ] Gantt-like positions are deterministic from dates and lanes.
- [ ] Dagre or ELK is chosen explicitly for dependency layout; React Flow is not described as providing automatic layout.
- [ ] Feature, requirement, and architectural decision relationships use stable IDs and typed nodes/edges.
- [ ] Docusaurus uses `BrowserOnly`, or the advanced React Flow 12 SSR dimensions are fully configured.
- [ ] The canvas has explicit width and height.
- [ ] Documentation views disable dragging, connecting, and deletion.
- [ ] Keyboard and screen-reader support remains enabled.
- [ ] Sharp styling applies `border-radius: 0` to nodes, controls, minimaps, filters, and surrounding panels.
- [ ] Every visualization has a semantic table fallback derived from the same adapter.
- [ ] Unit, component, type, production build, browser, Actions, and deployed-route checks pass.