Display
Diagram
A flow or architecture figure, drawn out of the system’s own parts.
Usage
When to reach for it
import { Diagram } from '@misoto22/design'Notes
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.
Anatomy
| Element | Description |
|---|---|
| Framerequired | The <figure role="group"> 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 <div>, not a <figcaption>, 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.
Examples
default
A request, drawn as three ranks with the work nested inside the middle one. Only the nodes an edge names carry an id, and each edge is written in the order the array runs: an edge is matched against the node immediately before this one, so one written to-from, or between two nodes that are not neighbours, draws nothing — and says so in development, as DIAGRAM_EDGE_NOT_ADJACENT, or DIAGRAM_EDGE_UNKNOWN_NODE when the id belongs to no node at all. Three more spec mistakes warn the same way: DIAGRAM_DUPLICATE_ID, DIAGRAM_ACCENT_ON_CONTAINER for accent on a node with children, which is drawn as a band and has no fill to take, and DIAGRAM_DIRECTION_ON_LEAF for direction on a node with none. The caption names the figure for a screen reader as well as for a reader.
containment not wiring
Structure with no flow in it: no edges, just nesting. A node WITH children is drawn as a labelled hairline band and a node without is a plate, which is what keeps a figure three levels deep from carrying three borders around anything inside it. That also means accent paints only on a plate — set on a container it compiles, type-checks and shows nothing, because a band has no fill to take.
a column of ranks
The same machinery turned on its side. spec.direction stacks the top rank and the arrows turn with it, which is also what a row does on its own below the sm breakpoint — so a row of six plates that reads as a pipeline on a desktop is six stacked boxes and five arrows on a phone. A child rank keeps its own axis: direction is read from the node that HAS children and never inherits from the rank above, which is why the three stores below still sit in a row.
the node it is about
One accented plate, which is the whole budget: accent is the system's only fill, so a figure with three of them is a figure about nothing. footnote prints under the box and outside it, for the sentence a note is too short to hold. This spec has no caption, so label is what names the figure's group — with neither, a screen reader announces a group and never says what of.
Accessibility
- A <figure> 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.