Skip to content

Web component

Use <flowmark-diagram> when the browser needs pan, zoom, theme switching, source updates, or animation controls and your application is not specifically React-first.

Terminal window
pnpm add @ministryplace/flowmark-element @ministryplace/flowmark

Import the element once from your browser entry point:

example.ts
import "@ministryplace/flowmark-element";

Then use ordinary HTML:

index.html
<flowmark-diagram
id="checkout-diagram"
theme="auto"
height="440"
frameless
animation="Order path"
animation-controls
></flowmark-diagram>
<script type="module">
const diagram = document.querySelector("#checkout-diagram");
diagram.source = `diagram "Checkout" {
api: gateway "API"
checkout: service "Checkout"
api -> checkout
animation "Order path" {}
}`;
await diagram.ready();
</script>

Assign non-trivial source through the JavaScript property. Putting a multiline language inside an HTML attribute creates escaping problems and unreadable templates.

For a no-build page, import the published package directly from esm.sh:

index.html
<flowmark-diagram id="checkout" theme="auto" height="440"></flowmark-diagram>
<script type="module">
import "https://esm.sh/@ministryplace/[email protected]";
const diagram = document.querySelector("#checkout");
diagram.source = `diagram "Checkout" {
direction LR
browser: client "Web app"
api: gateway "API"
checkout: service "Checkout"
browser -> api "POST /orders"
api -> checkout
}`;
await diagram.ready();
</script>

The package includes the element’s structural styles, so this example needs no Flowmark stylesheet. Replace x.y.z with the package version you have chosen and pin it in the URL. For an application build, prefer an installed dependency and a lockfile; that gives you repeatable builds and avoids making esm.sh part of your runtime availability and content-security policy. esm.sh supports this package@version URL form in modern browsers, as documented in its usage guide.

Name Type Default Purpose
source string "" Flowmark source; updates rerender in place
theme dark, light, auto, or registered name auto auto follows html[data-theme]
height number or CSS length 420 viewport height
frameless boolean false remove the border and panel background
show-theme-toggle boolean true built-in light/dark control
show-view-controls boolean true zoom, fit, and fullscreen controls
show-stats boolean false compact render timing badge
animation-controls boolean true playback bar when animations exist
autoplay boolean false begin playback after the first render
loop boolean false loop the selected animation
animation string first available preferred animation name or ID

Boolean attributes are enabled by presence. Use show-view-controls="false" when you need to turn off a default-on control.

Use frameless when the diagram should sit directly in a page composition rather than look like a separate widget. It only removes the outer border and panel background; control visibility remains governed by the control attributes.

The built-in chrome behaves like a video player: controls appear when the reader moves the pointer, clicks, or uses the keyboard, then fade after a short idle period. A focused control stays visible, so keyboard users do not lose their place. This behavior is automatic and does not change the attributes above.

ready() resolves after the first render. The element also dispatches flowmark-render with the RenderResult in event.detail after later updates:

example.ts
diagram.addEventListener("flowmark-render", (event) => {
if (!event.detail.ok) console.error(event.detail.diagnostics);
});
diagram.source = nextSource;

View methods include fit(), zoomIn(), zoomOut(), and resetView().

With theme="auto", the element reads document.documentElement.dataset.theme. Update that value when the host theme changes. Import @ministryplace/flowmark/theme.css only when you want to bridge or override Flowmark variables from host CSS; the element already carries its structural styles.

If you use React, prefer the typed React wrapper instead of teaching JSX about a custom element manually.