Diagrams
DiagramCanvas
A frame that a picture larger than it can be panned and zoomed inside.
Ships from@misoto22/design/diagrams
When to reach for it
Examples
default
4 elements and 3 relationships.
- Browser (external)
- CloudFront (cloud) — CDN
- API (backend) — FastAPI
- Postgres (database)
- Browser → CloudFront: HTTPS
- CloudFront → API
- API → Postgres: SQL
Drag to pan. Plus and minus zoom, zero resets, the arrow keys pan.
Notes
A frame that a picture larger than it can be moved around inside.
Pan with a drag, zoom with the controls or with ⌘/Ctrl and the wheel, and reset with a key. That is the whole of it — this is deliberately a VIEWPORT and not a diagram editor: nothing here knows what a node is, so it works for any oversized figure, an SVG, an image, a table that will not fold.
Three decisions here are not obvious.
A plain wheel scrolls the page, not the diagram. A canvas that swallows the wheel is a scroll trap: a reader flicking down an article hits the figure and the page stops moving for no reason they can see. Zooming needs the modifier — which is also the platform gesture for zoom everywhere else, and is what a trackpad pinch already sends.
The transform is on a wrapper, not on the content. The child keeps its own coordinate space, so a figure inside can still be measured, exported and read by anything that walks it. Scaling the child directly would make every getBoundingClientRect inside it a lie.
Keyboard first, and the frame is a real tab stop. + / - / 0 and the arrow keys move the view; the frame takes focus so they can be pressed at all. A canvas that only answers a drag is a canvas half the readers cannot operate.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| childrenrequired | ReactNode | — | |
| className | string | — | |
| controls | boolean | true | Hides the built-in zoom controls, for a caller supplying its own. |
| height | string | '24rem' | How tall the frame is. Anything CSS accepts. |
| label | string | 'Diagram canvas' | Names the region for assistive tech. |
| onViewChange | (view: CanvasView) => void | Told about every view change, for a minimap or a percentage readout. | |
| ref | Ref<DiagramCanvasHandle> | — |
Keyboard
| Key | Does |
|---|---|
| += | Zooms in about the centre of the frame. |
| - | Zooms out. |
| 0 | Resets the scale and the offset together. |
| ←→↑↓ | Pans. Shift pans further per press. |
Accessibility
- The frame is a real tab stop, so the keyboard controls can be pressed at all.
- A plain wheel scrolls the page. Zoom needs the platform modifier, so the canvas is never a scroll trap in the middle of an article.