Components/Flowchart

Flowchart

Workflow nodes on a dotted canvas: category chips, card slots, automatic bezier connectors, draggable and always controlled.

VerifiedSince 0.6.0

Usage

Flowchart

Order workflow

A trigger and a condition branch; the connector recomputes from measured card heights, and dragging a card snaps its landing position to the dot grid.

Loading demo...

Best Practices

  • Give nodes on one run the same x so the connector degenerates to a straight line.
  • Let card content drive its own height; do not pin a card height — connectors are drawn from measured heights, and a pinned one puts the two out of step.
  • The chip's tone names a kind of step (trigger, branch, action), not a status, which is why it draws from the BUI accent set rather than the --tx-* semantic ramp.

API Reference

Props

NameTypeDefaultDescription
nodesFlowNode[]—Nodes on the canvas. Required.
edgesFlowEdge[][]Connections between nodes.
heightnumber333Canvas height in px.
nodeWidthnumber290Default node width, overridable per FlowNode.width.
gridnumber22Dot pitch, and the drag snap step.
dotsbooleantrueRender the dot grid.
draggablebooleanfalseAllow dragging nodes.
snapbooleantrueSnap dragged nodes to the grid.
ariaLabelstring'Workflow'Accessible name for the canvas region.

FlowNode requires id, x and y. label is the category chip above the card, tone is one of violet / orange / accent / green / red / neutral, width overrides a single node's width, and draggable turns dragging off for one node.

Events

NamePayloadDescription
node-move{ id, x, y }A node finished being dragged. The component does not touch nodes, so the host must write the position back for the move to persist.
node-click{ id, node }A node was clicked, or activated with Enter / Space while focused.

Slots

NameScopeDescription
node{ node, index }Card content. Without it the node renders an empty card.
label{ node }Replaces the category chip above the card.

Coordinates

x is the node's horizontal centre, not its left edge — nodes sit astride that line via translateX(-50%), so everything on one vertical run shares an x without the host needing to know how wide a card is. y is the top edge. Both are CSS pixels inside the canvas.

grid is both the dot pitch and the drag snap step, defaulting to 22px. The grid is a radial-gradient: the dot lands at 1px and falls off at 1.25px. A hard 1px stop aliases into a square at the grid size, and anything past about 1.5px becomes a texture competing with the cards.

Connectors

Each entry in edges runs from the bottom edge of from to the top edge of to. Card height is content-driven — a two-line condition is taller than a one-line trigger — so the component measures each card with a ResizeObserver and recomputes the path, instead of assuming a height that would put the tail inside or below the card.

Both control points sit past the midpoint and cross (±0.55 of the gap). A vertically-aligned pair therefore reads as a straight line, while an offset pair still leaves and enters its cards vertically rather than with the slack a 0.5 factor gives.

An edge naming a node that is not on the canvas is skipped rather than drawn to the origin, which would streak a line across the whole surface.

Overview

  • Always controlled. The component never writes nodes. During a drag it holds a temporary offset so the card tracks the pointer, then clears it and emits node-move on release; if the host does not write back, the node springs home. That is deliberate — undo stacks, alternative snapping and server persistence all belong to the host.
  • Draggable nodes carry touch-action: none, or a touch drag scrolls the page instead of moving the node.
  • Nodes are focusable. Each node is a tab stop, Enter / Space fires node-click, and :focus-visible draws the ring.
  • Connectors are drawn beneath the cards so a card's hairline ring covers the line's endpoint, rather than the line crossing the card's corner.

Technologies

  • Component source: packages/tuffex/packages/components/src/flowchart/src/TxFlowchart.vue.
  • Types: packages/tuffex/packages/components/src/flowchart/src/types.ts.
  • Ported from Beautiful UI (https://www.beautifului.dev) case 16, Flowchart, © 2026 Shane Levine, MIT.
查看源码
packages/tuffex/packages/components/src/flowchart/index.ts