# Diagram A flow or architecture figure, drawn out of the system’s own parts. - Group: Display - Import: `import { Diagram } from '@misoto22/folio'` - Page: https://ui.misoto22.com/components/diagram/ - Related: card, figure-band ## When to reach for it A picture of structure, in a page rather than in a terminal. Nesting is containment and an edge is a step between siblings — a diagram that needs arbitrary wiring wants a drawing, not this. ## Anatomy - **Frame** (required) — The
and the panel inside it: a --rule hairline on the --radius-lg corner over --paper-2, with fluid padding and overflow-x-auto on a hairline scrollbar — so a wide figure scrolls inside its own box instead of widening the page. - **Leaf plate** — A node with NO children: a bordered card on --paper, or filled with --accent when accent is set. Its label breaks inside itself, because an identifier like TenantMainMiddleware has no break opportunity and would otherwise run into the plate’s edge. - **Container band** — A node WITH children: a labelled hairline — ink at the top rank, --rule-2 below it — with its children underneath and no frame of its own. That is the whole design: drawing a container as another box puts three borders around anything two levels deep. - **Node note** — node.note, a mono line beside a band’s label or under a plate’s. One short line, a step back from the name. - **Edge mark** — The arrow between two adjacent siblings an edge names, with the edge’s label under it. aria-hidden, and rotated a quarter turn below the sm breakpoint, where a row of nodes stacks into a column and the arrow has to point the way the layout actually runs. - **Caption** — spec.caption, printed under the frame — as a
, not a
, because an article stylesheet styles figcaption unlayered and an unlayered rule beats a utility whatever the specificity. ## Best practices ### Do - Write an edge from a node to the node immediately after it in the same rank, in that order. An edge between non-adjacent nodes, or one written to→from, draws no arrow — and now says so in the console rather than leaving the author to spot a missing arrow in a picture that otherwise looks finished. - Keep ids unique across the whole spec. Each edge is now spent at the first pair that matches it, so a reused pair no longer draws the arrow twice — but the arrow lands on whichever pair comes first, which is a diagram asserting something nobody wrote. - Give the spec a caption or a label. The figure’s role="group" is named by whichever is present, and with neither the reader is told there is a group and never told what of. ### Don’t - accent is read only in the plate branch, so setting it on a node with children compiles, type-checks and paints nothing — a container is a band, and a band has no fill to take. Development says so; a production build does not. - direction is read only from a node that HAS children. Set on a leaf it is ignored, because the axis a leaf sits on belongs to its parent — and, like accent on a band, it is reported in development rather than silently dropped. - Do not put six nodes across the top rank. A row is flex-col below sm and only flex-row above it, so a figure that reads as a pipeline on a desktop is six stacked plates and five arrows on a phone. ## Accessibility - A
with role="group", named by its caption, so the whole picture is one thing a reader can skip. - Arrows are aria-hidden: assistive tech reads the nodes in document order and has no use for a glyph pointing at the next one. - Server-rendered markup, not a canvas — every label is real text a screen reader and a search engine can read. - A spec the renderer cannot honour — an unmatched edge, a duplicate id, accent on a band, direction on a leaf — prints a named warning in development, because the alternative is a confident picture of something else. ## Diagram A flow or architecture diagram, drawn out of the system's own parts. The alternative it replaces is a fenced block of box-drawing characters — `┌──────┬──────┐` — which is a picture rendered in a font chosen for code. It inherits the code block's frame and scrollbar, so a diagram reads as terminal output; it cannot wrap, so on a phone it either overflows or is scaled to nothing; the box edges are text, so a screen reader reads the rules out loud; and none of it responds to the theme. The other alternative is a diagramming library, which is several hundred kilobytes of layout engine, renders after hydration, and draws in its own palette. This is neither: hairline frames on the radius scale, mono labels, the muted step for anything supporting — so a diagram belongs to the page it sits on. It server-renders, because it is markup. NESTING IS CONTAINMENT, which is what most architecture diagrams actually describe: this is inside that, and these two sit beside each other. Edges are for the sequence between siblings, not for arbitrary wiring — a diagram that needs arbitrary wiring is a diagram that wants a drawing, and this will not pretend otherwise. It takes a spec rather than markup, so a fenced ```diagram block in an article and a hand-written figure on a page are one renderer and one look — and a wrong diagram is corrected by editing data. ### Props - `spec` (required) — `DiagramSpec`. - `className` — `string`. ## Example — default ```tsx import { Diagram } from '@misoto22/folio' ``` ## Example — containment not wiring ```tsx import { Diagram } from '@misoto22/folio' ``` ## Example — a column of ranks ```tsx import { Diagram } from '@misoto22/folio' ``` ## Example — the node it is about ```tsx import { Diagram } from '@misoto22/folio' ```