Skip to content

Chain

FluxFlowChain positions a run of nodes and wires them together. Give it a starting point and it hands every Node inside it a position, so a straight sequence of steps no longer needs a coordinate per card.

A link keeps its own id, so connectors from outside the chain reference it exactly as they always have.

New orderShopify
Charge the card
Email the receipt

TIP

Absolute x and y on a node stay the source of truth for positions. A chain only fills them in for the nodes it holds; give a node its own x and y and it keeps them, stepping out of the layout while staying in the markup.

Props

x?: number
The horizontal position the chain starts at, in flow coordinates.

y?: number
The vertical position the chain starts at, in flow coordinates.

gap?: number
The space, in pixels, between two links.
Default: 60

labelGap?: number
The space between two links whose connector carries a label or an icon, since a badge needs more room than the plain gap leaves. Defaults to 105 on a vertical chain and 210 on a horizontal one, and never drops below `gap`.

direction?: 'horizontal' | 'vertical'
The axis the links run on. `vertical` stacks them top to bottom, `horizontal` from left to right.
Default: vertical

align?: 'start' | 'center' | 'end'
How links of different sizes line up across the run. `center` puts their middles on one line, which is what keeps the connectors straight.
Default: center

autoConnect?: boolean
Draws a connector between every two neighbouring links. Turn it off to wire the chain up yourself.
Default: true

Slots

default
The links of the chain. Place FluxFlowNode components here, plus any FluxFlowConnection that should replace an automatic one.

Examples

Mixed sizes

A terminal, a pill and a card are all different widths. With align="center" their middles land on one line, so the connectors run dead straight through the whole run.

Start
File uploaded
Scan for malware
Stored

<template>
    <FluxFlow :padding="21">
        <FluxFlowChain :gap="45">
            <FluxFlowNode id="start">
                <FluxFlowTerminal label="Start" color="success"/>
            </FluxFlowNode>

            <FluxFlowNode id="upload">
                <FluxFlowPill icon="bolt" label="File uploaded" color="info"/>
            </FluxFlowNode>

            <FluxFlowNode id="scan">
                <FluxFlowActionCard title="Scan for malware" icon="robot"/>
            </FluxFlowNode>

            <FluxFlowNode id="done">
                <FluxFlowTerminal label="Stored"/>
            </FluxFlowNode>
        </FluxFlowChain>
    </FluxFlow>
</template>

<script
    setup
    lang="ts">
    import { FluxFlow, FluxFlowActionCard, FluxFlowChain, FluxFlowNode, FluxFlowPill, FluxFlowTerminal } from '@flux-ui/flow';
</script>

Horizontal

Set direction="horizontal" to run the chain from left to right. Links line up on their middles across the run, the same way they do vertically.

Draft
In review
Approved
Published

<template>
    <FluxFlow :padding="21">
        <FluxFlowChain
            direction="horizontal"
            :gap="45">
            <FluxFlowNode id="draft">
                <FluxFlowTerminal label="Draft"/>
            </FluxFlowNode>

            <FluxFlowNode id="review">
                <FluxFlowPill icon="user-check" label="In review" color="info"/>
            </FluxFlowNode>

            <FluxFlowNode id="approved">
                <FluxFlowPill icon="circle-check" label="Approved" color="success"/>
            </FluxFlowNode>

            <FluxFlowNode id="published">
                <FluxFlowTerminal label="Published" color="success"/>
            </FluxFlowNode>
        </FluxFlowChain>
    </FluxFlow>
</template>

<script
    setup
    lang="ts">
    import { FluxFlow, FluxFlowChain, FluxFlowNode, FluxFlowPill, FluxFlowTerminal } from '@flux-ui/flow';
</script>

Your own connector

A FluxFlowConnection written between two links replaces the automatic one, so a labelled or colored connector never doubles up with a plain one. A side branch stays outside the chain and references the link by id.

Push to mainGitHub
Build the image
Deploy to production
Alert the on-call

<template>
    <FluxFlow :padding="21">
        <FluxFlowChain>
            <FluxFlowNode id="push">
                <FluxFlowTriggerCard title="Push to main" subtitle="GitHub"/>
            </FluxFlowNode>

            <FluxFlowConnection
                from="push"
                to="build"
                color="primary"
                label="On main"/>

            <FluxFlowNode id="build">
                <FluxFlowActionCard title="Build the image" icon="box"/>
            </FluxFlowNode>

            <FluxFlowNode id="deploy">
                <FluxFlowActionCard title="Deploy to production" icon="rocket"/>
            </FluxFlowNode>
        </FluxFlowChain>

        <FluxFlowNode id="alert" :x="411" :y="280">
            <FluxFlowActionCard title="Alert the on-call" icon="bell" color="danger"/>
        </FluxFlowNode>

        <FluxFlowConnection
            dashed
            from="build"
            to="alert"
            from-side="right"
            color="danger"
            label="Build failed"/>
    </FluxFlow>
</template>

<script
    setup
    lang="ts">
    import { FluxFlow, FluxFlowActionCard, FluxFlowChain, FluxFlowConnection, FluxFlowNode, FluxFlowTriggerCard } from '@flux-ui/flow';
</script>

Labelled connectors

A connector that carries a label or an icon gets a wider segment, so the badge sits clear of both cards with a stretch of line on either side. Tune it with label-gap when your labels run long.

Contract reviewed
Collect the signatures
Archive the contract

<template>
    <FluxFlow :padding="21">
        <FluxFlowChain>
            <FluxFlowNode id="review">
                <FluxFlowConditionCard title="Contract reviewed"/>
            </FluxFlowNode>

            <FluxFlowConnection
                from="review"
                to="sign"
                color="success"
                label="Approved"/>

            <FluxFlowNode id="sign">
                <FluxFlowActionCard title="Collect the signatures" icon="user-check"/>
            </FluxFlowNode>

            <FluxFlowConnection
                from="sign"
                to="archive"
                color="primary"
                icon="circle-check"
                label="Signed"/>

            <FluxFlowNode id="archive">
                <FluxFlowActionCard title="Archive the contract" icon="database"/>
            </FluxFlowNode>
        </FluxFlowChain>
    </FluxFlow>
</template>

<script
    setup
    lang="ts">
    import { FluxFlow, FluxFlowActionCard, FluxFlowChain, FluxFlowConditionCard, FluxFlowConnection, FluxFlowNode } from '@flux-ui/flow';
</script>

TIP

A chain only claims the pairs it can see: a connector between two links has to sit inside the chain, in the same direction, to replace the automatic one. Set :auto-connect="false" to draw every connector yourself.

Used components

See also

  • useFlowLayout for a graph that branches instead of running in a line.