API Reference
The complete surface: the two module functions, every instance method, the full config schema, and the CSS tokens. New to FlowKit? Start with Quick Start — this page assumes you've already seen a stage boot.
FlowKit.create()
Mounts a stage into an element you already control the size of.
| Param | Type | Description |
|---|---|---|
| rootEl | HTMLElement | Must already carry class fk-root and have a CSS size (width/height, or fill a sized parent). FlowKit reads its box on every draw(). |
| config | object | See Config schema. |
Returns a FlowKitInstance — see Instance methods. create() does not call setView() for you; call it once yourself right after.
const root = document.getElementById('app'); // class="fk-root", sized via CSS
const app = FlowKit.create(root, config);
app.setView('motor');
FlowKit.embed()
Mounts a stage at a fixed design size inside any container and scales it to the container's current width, refitting on a ResizeObserver.
| Param | Type | Description |
|---|---|---|
| containerEl | HTMLElement | Any block-level element. Its width (not height) drives the scale factor; a .fk-embed wrapper is appended inside it. |
| config | object | See Config schema. |
| opts.width | number | Design canvas width in px. Default 1600. |
| opts.height | number | Design canvas height in px. Default 855. |
| opts.responsive | boolean | Default: true. Below a container width of 700px, use a readable stacked layout. Set false to keep proportional scaling at every width. |
| opts.view | string | View name to call setView() with on mount. Default: the first key of config.center.views. |
| opts.select | string | Outcome id to call selectOutcome() with on mount. Default: none. |
Returns a FlowKitInstance. Its destroy() also disconnects the internal ResizeObserver and removes the wrapper.
const app = FlowKit.embed(document.getElementById('demo'), config, {
view: 'motor',
select: 'checkout',
});
Instance methods
Both create() and embed() return the same shape.
setView(name)
Swaps the center card to config.center.views[name]: sets the header tag, the card height, the dashed style, re-runs render() into the body, updates the footer toggle, and redraws the wires. An unknown name is silently ignored. The toggle button (shown when the active view has a toggleLabel) calls this internally to cycle Object.keys(config.center.views).
app.setView('interior');selectOutcome(id)
The click behavior behind an outcome button, callable directly. Rings the matching outcomes[] entry, sets the card's output value and color from it, calls setActiveSource(outcome.source) when the outcome has one (otherwise just redraws), and pins its callout. An unknown id is a no-op.
app.selectOutcome('checkout');setActiveSource(id)
Bolds the label and brightens the dot for the matching sources[] row (and only that one), then redraws so its wire gets the bright "spark" overlay.
app.setActiveSource('productos');setActiveOutcome(id)
Rings the matching outcome button only — no output-value change, no callout, no source highlight, no redraw. selectOutcome() calls this internally; call it directly when you want just the ring.
app.setActiveOutcome('checkout');showCallout(html, pos)
Appends a free-form .fk-callout card to the stage at pos.left / pos.top (any CSS length string, positioned relative to the stage). Unlike the hover/select callout, this one isn't tracked or deduplicated internally — each call adds a new node. Remove it yourself (the returned element's .remove()) when you're done with it.
const co = app.showCallout('<b>Custom note</b>', { left: '40px', top: '80px' });
// later: co.remove();addChip(sourceId, t, html)
Drops a .fk-chip pill on the wire belonging to sourceId (a sources[].id — not an outcome), at fraction t along it: 0 sits at the source dot, 1 at the card edge. The chip is tracked internally and repositions itself on every draw() (including the automatic redraw on window resize).
app.addChip('ordenes', 0.42, '<i></i><span>New order</span>');draw()
Recomputes every wire path, pulse, arrowhead and chip position from the current DOM layout. Runs automatically on window resize and once again after web fonts finish loading (glyph widths shift on first paint). Call it yourself after anything else that moves the sources, outcomes or card — for example, injecting new DOM near the stage.
app.draw();setPaused(paused)
Pause or resume the animated flow wires. The stage playback button uses this method and exposes its state with aria-pressed. The stylesheet also respects the system reduced-motion preference.
destroy()
Removes the resize listener and the stage's DOM. On an embed() instance it additionally disconnects the ResizeObserver and removes the outer wrapper.
app.destroy();Config schema
Every field FlowKit reads from the config object, grouped by where it lives.
Top level
| Field | Type | Required | Description |
|---|---|---|---|
| headers | object | Yes | { left, right } — the column captions above the sources and outcomes. |
| sources | array | Yes | Left-column entries. See sources[] below. |
| outcomes | array | Yes | Right-column entries. See outcomes[] below. |
| center | object | Yes | The center card: brand, logo, output label/value, and views. See center below. |
| pulses | object | No | Animated wires, keyed by source id. See pulses[sourceId] below. A source with no entry renders a plain static wire. |
| feedback | object | Yes | { icon, label } for the bottom feedback-loop caption. |
sources[]
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Unique. Referenced by outcomes[].source, pulses, setActiveSource(), and addChip(). |
| label | string | Yes | Text next to the dot. |
| icon | string | Yes | Inline <svg> markup, rendered around 22×22. |
outcomes[]
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Unique. Passed to selectOutcome() / setActiveOutcome(). |
| label | string | Yes | Button text. |
| icon | string | Yes | Inline <svg> markup, rendered around 21×21. |
| accent | string | Yes | Hex color. Tints the icon and colors the active ring, glow, and callout. |
| source | string | No | A sources[].id to activate (via setActiveSource) when this outcome is selected. |
| callout | object | No | { line1, line2, value, unit }, see below. Omit to disable both the hover preview and the click callout for this outcome. |
outcomes[].callout
| Field | Type | Required | Description |
|---|---|---|---|
| line1 | string | Yes* | First preview line. |
| line2 | string | Yes* | Second preview line. |
| value | string | Yes* | The big number, e.g. '+$49'. |
| unit | string | Yes* | Caption next to the value. |
* only required if the outcome includes a callout at all.
sources and outcomes want two or more entries. Their vertical spacing is computed as index / (length - 1); with a single entry that divides by zero, and the wire just fails to draw instead of throwing.
center
| Field | Type | Required | Description |
|---|---|---|---|
| brand | string | Yes | Card header title. |
| logo | string | Yes | Inline <svg> markup, 24×24, left of brand. |
| outputLabel | string | Yes | Small caption for the footer value, e.g. 'Output'. |
| outputValue | string | Yes | Initial footer value; overwritten by selectOutcome(). |
| views | object | Yes | Keyed by view name → { tag, height, dashed, toggleLabel, render }. See below. |
center.views[name]
| Field | Type | Required | Description |
|---|---|---|---|
| tag | string | Yes | Small uppercase label in the card header. |
| height | number | Yes | Card height in px, at the 1600×855 design size. |
| dashed | boolean | No | Default false. true switches the card to a dashed "ghost" border. |
| toggleLabel | string | No | Footer toggle text, e.g. 'see the engine'. Omit to hide the toggle. Clicking it advances to the next key in views. |
| html | string | Either html or render | Static body markup. Use this form for JSON configurations. Only supply markup you trust. |
| render | function | Either render or html | () => htmlString. Called on every setView() to fill the card body. |
pulses[sourceId]
| Field | Type | Required | Description |
|---|---|---|---|
| dash | string | No | Default '9 91'. SVG stroke-dasharray. A 4-value dasharray (e.g. '6 2 10 82') renders a static double-dash pattern with no separate comet tail. |
| dur | number | No | Default 5.2. Loop duration in seconds. |
| delay | number | No | Default 0. Negative animation-delay to desync parallel pulses. |
| soft | boolean | No | Default false. Dimmer, thinner style for a background pulse. |
| stops | array | No | Default ['#f3a8ec','#c4b5fd','#8f83f3']. Hex colors along the wire's gradient. |
feedback
| Field | Type | Required | Description |
|---|---|---|---|
| icon | string | Yes | Inline <svg> markup, 18×18. |
| label | string | Yes | Caption text, e.g. 'Learns from the result'. |
CSS tokens
Declared on :root in flowkit.css, read inside .fk-root. Override on :root to theme every stage, or on one stage's own element to scope it — see Theming.
| Token | Default | Affects |
|---|---|---|
| --fk-page-bg | #050408 | Background of .fk-root itself, behind the corner glows and the stage panel. |
| --fk-stage-bg | #0c0b12 | Declared, not yet wired to a rule — the stage panel currently uses fixed gradients. Reserved. |
| --fk-stage-border | #1c1b26 | Border of the stage panel. |
| --fk-text | #e6e4ee | Default text color for the whole root. |
| --fk-text-dim | #8b8a98 | The "Data sources" / "Outcomes" column header text. |
| --fk-text-faint | #55545f | Declared, not yet wired to a rule. Reserved. |
| --fk-wire | #2b2a36 | Stroke color of the static (non-pulsing) connector wires. |
| --fk-panel | #14131c | Declared, not yet wired to a rule — view panels (.fk-panel) use fixed colors today. Reserved. |
| --fk-panel-border | #232230 | Declared, not yet wired to a rule. Reserved. |
| --fk-accent | #a78bfa | Declared, not yet wired to a rule — each outcome sets its own --accent inline from accent instead. |
| --fk-amber | #f0a832 | The output value, and every callout's tag dot / value color, independent of an outcome's own accent. |
| --fk-font | 'Poppins', … | Font stack for the whole root. |
Stage size & scaling
The stage's internal layout — header offsets, column widths, the 474px center card, all its padding and gaps — is authored in fixed pixels in flowkit.css against a 1600×855 canvas. Nothing about that layout is percentage-based, so it only looks right at or above roughly that size.
- For a stage that has that much room on its own — typically a full-screen app — use
create()directly on a root sized by CSS (position:fixed;inset:0and similar). No scaling happens; the layout renders at its natural size. - For a stage inside a narrower container — a docs page, a card, a gallery thumbnail — use
embed(). It mounts the real 1600×855 stage and applies one CSStransform: scale()to fit the container's width, at widths of 700px and above. Below that, the default responsive layout stacks sources, the center card, and outcomes. Setresponsive: falseto keep scaling at every width.
What doesn't work well: calling create() on a root sized well below ~1200×650. The sources column, the outcomes column, and the center card are each positioned independently by fixed offsets from the stage edges, so below that width the center card overlaps the side columns instead of scaling down to make room.