Mermaid
Render Mermaid diagrams (flowcharts, sequence, class, state,
gantt…) as a framework-agnostic web component. <r-mermaid> lazy-loads the mermaid library
on first render (apps that never use it pay nothing) and draws the diagram into its shadow
root, so it's isolated from page styles.
Use when you want to drop a diagram from text into any page without wiring up mermaid yourself, optionally with a copy / download / fullscreen toolbar and pan-zoom viewer.
Quick Start
<r-mermaid>graph LR; A[Request] --> B[Validate]; B --> C[Store]</r-mermaid>import 'ranui'; // or the standalone entry:
import 'ranui/mermaid';The diagram source is read from the element's text content, or from a URI-encoded
code attribute (use code when the syntax contains <, e.g. classDiagram <|--,
so it survives HTML parsing):
el.code = 'classDiagram\n Dog --|> Animal'; // property setter URI-encodes for youControls
Every control is opt-in via a boolean attribute; a bare <r-mermaid> is a clean static
diagram. Enabled controls remain visible above the diagram.
<r-mermaid copy download fullscreen>graph TD; A --> B; B --> C</r-mermaid>- copy: copies the diagram source to the clipboard.
- download: SVG / PNG / source (
.mmd); a single format downloads directly, multiple show a menu. Restrict withdownload="svg"ordownload="svg png". - fullscreen: opens a headerless lightbox (r-modal) with pan & zoom (wheel to zoom,
drag to pan, reset); close via the ✕, backdrop click, or
Esc.
API Reference
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
code |
string (URI-encoded) |
— | Diagram source. Falls back to the element's text content when absent. |
theme |
'auto' | 'light' | 'dark' |
'auto' |
Mermaid theme. auto follows the page (.dark / [data-ran-theme]) and re-renders on toggle. |
copy |
boolean | off | Show the copy-source button. |
download |
boolean / "svg png source" |
off | Show the download button; value restricts the offered formats. |
fullscreen |
boolean | off | Show the fullscreen button. |
sheet |
string |
— | Extra CSS injected into the shadow root. |
label-* |
string |
English | Override control labels: label-copy, label-download, label-fullscreen, label-zoom-in, label-zoom-out, label-reset, label-diagram (fullscreen dialog name). |
Events
All events bubble and cross the shadow boundary (composed).
| Event | detail |
Fired when |
|---|---|---|
render |
{ ok: true } |
a diagram finished rendering |
copied |
{ kind: 'source' } |
the source was copied |
download |
{ format: 'svg' | 'png' | 'source' } |
a file was downloaded |
error |
{ message: string } |
the diagram failed to parse/render |
fullscreenchange |
{ open: boolean } |
the fullscreen lightbox opened/closed |
CSS Parts
| Part | Description |
|---|---|
mermaid |
The outer wrapper. |
diagram |
The rendered-diagram container. |
toolbar |
The visible action row. |
button |
Each toolbar icon button. |
error |
The error message box (on render failure). |
r-mermaid::part(toolbar) {
background: var(--surface);
}CSS Variables
Override on the element (each falls back to a semantic token, then a literal):
--ran-mermaid-padding, --ran-mermaid-toolbar-background, --ran-mermaid-toolbar-gap,
--ran-mermaid-button-size, --ran-mermaid-button-color, --ran-mermaid-button-hover-background,
--ran-mermaid-error-color.
Notes
- Lazy-loaded: mermaid (and the r-modal used for fullscreen) are dynamic imports, so they arrive as separate async chunks only when a diagram renders / fullscreen opens.
- Rendering fidelity:
<r-mermaid>uses mermaid's own render, so all diagram types and themes are supported. - PNG export: diagrams that use HTML labels (mermaid
htmlLabels) render via<foreignObject>, which can taint the canvas and make PNG export fail; anerrorevent is dispatched in that case. SVG and source export always work.
Copy and narrow screens
Enabled controls stay visible in a quiet row above the content: 32px targets for fine pointers, 44px for touch, with an 8px gap. Without controls, no row space is reserved. Copy keeps focus and prevents duplicate writes while pending. Clipboard rejection or unavailability appears locally in ::part(copy-status) (role="status"), localized with label-copy-error; retry uses the same button. copied fires only after the current content reaches the clipboard. A source or copy-target change invalidates feedback from older requests. A source-only update preserves the focused button and allows copying the new source immediately.