Flow
A pipeline, dependency graph or database schema on a pannable canvas: steps with a status, smooth edges, rows joined row to row, auto layout, draggable nodes saved to localStorage, a hover card and a context menu.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
nodes | FlowNode[] | [] | The steps. A property, or a JSON attribute. |
edges | FlowEdge[] | [] | The dependencies between steps. A property, or a JSON attribute. |
direction | FlowDirection | LR | Main axis of the auto layout. The user can switch it from the context menu; the choice is saved with the layout. |
edge-type | FlowEdgeType | bezier | Edge shape: smooth curves or rounded orthogonal segments. |
storage-key | string | — | localStorage key the custom layout and direction are saved under. Empty disables persistence. |
editable | boolean | false | Lets the user add, rename, connect and delete nodes and delete edges. The flow fires node-add, node-edit,
node-delete, edge-add and edge-delete and the application updates nodes and edges. |
no-double-click-add | boolean | false | Turns off adding a node by double-clicking (or double-tapping) empty canvas, for an application whose actions
toolbar has an add button calling addNode(): a double-click then only selects nothing, and no node appears
where the user merely meant to deselect or zoom. The canvas menu's Add node, N and Enter still add one. |
actions-placement | FlowActionsPlacement | top | Edge of the canvas the actions toolbar sits on: top or bottom lay the buttons out in a row, left or right in a column (and the arrow keys follow). |
fit-min-zoom | CustomEvent | DEFAULT_FIT_MIN_ZOOM | Least zoom fitting the view may choose (fitView(), the first render, a resize or new data while the user has
not panned or zoomed), from 0.25 to 1. A flow too large for its box at this zoom shows its start instead of its
middle: the first rank sits at the left edge (LR) or the top edge (TB), centred across if it fits that way.
Raise it for a small preview whose labels must stay readable. Zooming by hand still goes down to 25%. |
row-limit | number | 0 | How many rows a node shows before the rest fold into a "+ N more" row the user clicks to show them (Shift+Enter or
the context menu from the keyboard); a node's own rowLimit wins. Rows an edge meets always show. 0 shows every
row. Which nodes are open is saved with the layout under storage-key. |
locked | boolean | false | Turns off moving nodes; panning, zooming, selection and the hover card still work. |
selected | string | null | null | Id of the selected node, or null. |
no-card | boolean | false | Turns off the hover card. |
no-context-menu | boolean | false | Turns off the context menu, so the browser shows its own. |
open-delay | number | 400 | Delay before the hover card opens, in milliseconds. |
close-delay | number | 200 | Delay before the hover card closes once the pointer or focus has left the node and the card, in milliseconds. |
Slots
| Name | Description |
|---|---|
node:{id} | Body of the node whose id is {id}, e.g. slot="node:build". Replaces renderNode and the default body for that node. |
card:{id} | Content of the hover card of node {id}. Replaces renderCard and the default card for that node. |
actions | Buttons drawn over the canvas, along the edge actions-placement names, e.g. add node, auto layout (resetLayout()) or fit view (fitView()). They form a toolbar: the arrow keys move between them. |
Events
| Name | Type | Description |
|---|---|---|
layout-change | CustomEvent<FlowLayoutChangeDetail> | The user moved a node, switched direction or went back to auto layout, or setLayout() was called. Does not bubble. |
selection-change | CustomEvent<FlowSelectionChangeDetail> | The selected node changed through the user. detail.selected is its id, or null. Does not bubble. |
node-click | CustomEvent<FlowNodeEventDetail> | A node was clicked, activated with Enter or Space, or chosen with a flow:details context-menu row. Does not bubble. |
rows-toggle | CustomEvent<FlowRowsToggleDetail> | The user showed or folded the rows of node detail.id past the row-limit (the "+ N more" row, Shift+Enter or the context menu). Does not bubble. |
row-move | CustomEvent<FlowRowMoveDetail> | editable only: the user moved row detail.row of node detail.id from index detail.from to detail.to of its rows, by its grip, the keyboard (R) or the row's context menu. Move it in rows. Does not bubble. |
node-add | CustomEvent<FlowNodeAddDetail> | editable only: the user asked for a node at detail.position (canvas pixels, the node's top-left corner), connected from detail.source (by its side detail.sourceSide, into the new node's detail.targetSide) when it came from a connection dropped on empty canvas. Append it to nodes. Does not bubble. |
edge-add | CustomEvent<FlowEdgeAddDetail> | editable only: the user connected detail.source to detail.target, from side detail.sourceSide of the source to side detail.targetSide of the target, or between rows detail.sourcePort and detail.targetPort (an end on a row has no side: it faces the other end). Never an existing edge, nor a self-loop except between two different rows of one node. Does not bubble. |
node-delete | CustomEvent<FlowNodeDeleteDetail> | editable only: the user asked to delete node detail.id. Does not bubble. |
edge-delete | CustomEvent<FlowEdgeEventDetail> | editable only: the user asked to delete the edge from detail.source to detail.target. Does not bubble. |
edge-edit | CustomEvent<FlowEdgeEditDetail> | editable only: the user changed the label of the edge from detail.source to detail.target to detail.label with the inline editor; an empty label removes it. Does not bubble. |
node-edit | CustomEvent<FlowNodeEditDetail> | editable only: the user renamed node detail.id to detail.label with the inline editor. Does not bubble. |
flow-menu-select | CustomEvent<FlowMenuSelectDetail> | A context-menu row added by renderContextMenu was activated, with the node it was opened on. Does not bubble. |
CSS parts
Shadow DOM styling hooks used with ::part(name). Prefer CSS custom properties when they cover the change.
| Name | Description |
|---|---|
actions | The toolbar around the actions slot. |
CSS custom properties
Grouped by semantic target and state from --c2-<component>__<target>__<state>--<property>. Click a group to collapse it; click a name to copy it.
| Name | Type | Default | Description |
|---|---|---|---|
--c2-flow--height | pixel | 480px | Height of the canvas. |
--c2-flow--background-color | color | #fafafa | Canvas background. |
--c2-flow--border | border | 1px solid #e4e4e7 | |
--c2-flow--border-radius | border-radius | 8px | |
--c2-flow--font-family | font-family | — | |
--c2-flow__actions--align | justify-content | flex-start | Where the actions toolbar sits along its edge: flex-start, center or flex-end. |
--c2-flow__actions--offset | pixel | 12px | Distance between the actions toolbar and the edge of the canvas. |
--c2-flow__actions--gap | pixel | 4px | Space between two action buttons. |
--c2-flow__actions--padding | padding | 4px | |
--c2-flow__actions--background-color | color | #ffffff | |
--c2-flow__actions--border | border | 1px solid #e4e4e7 | |
--c2-flow__actions--border-radius | border-radius | 8px | |
--c2-flow__actions--box-shadow | box-shadow | 0 1px 2px rgba(24, 24, 27, 0.06) | |
--c2-flow__dot--color | color | #ebebed | Colour of the canvas dot grid. |
--c2-flow__dot--size | pixel | 1px | Radius of one grid dot. |
--c2-flow__dot--gap | pixel | 20px | Spacing of the dot grid at 100% zoom; it scales with the zoom, within the two bounds below. |
--c2-flow__dot--min-gap | pixel | 14px | Smallest dot spacing, reached when zoomed out. |
--c2-flow__dot--max-gap | pixel | 32px | Largest dot spacing, reached when zoomed in. |
--c2-flow__rank--gap | pixel | 72px | Space between two ranks of the auto layout. |
--c2-flow__node--gap | pixel | 20px | Space between two nodes of the same rank. |
--c2-flow__node--width | pixel | 200px | |
--c2-flow__node--padding-top | padding | 10px | |
--c2-flow__node--padding-right | padding | 12px | |
--c2-flow__node--padding-bottom | padding | 10px | |
--c2-flow__node--padding-left | padding | 12px | |
--c2-flow__node--background-color | color | #ffffff | |
--c2-flow__node--color | color | #18181b | |
--c2-flow__node--border | border | 1px solid #bcbcc6 | |
--c2-flow__node--border-radius | border-radius | 8px | |
--c2-flow__node--box-shadow | box-shadow | 0 1px 2px rgba(24, 24, 27, 0.06) | |
--c2-flow__node--cursor | cursor | default | Pointer over a node that can be moved, its label and rows included; grab shows the hand there. A row's grip shows grab, a node being dragged grabbing, a node of a locked flow pointer. |
--c2-flow__node__hover--border-color | color | #a1a1aa | |
--c2-flow__node__selected--border-color | color | rgb(2, 101, 220) | |
--c2-flow__node__selected--box-shadow | box-shadow | 0 0 0 3px rgba(2, 101, 220, 0.2) | |
--c2-flow__node__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | |
--c2-flow__node__dragging--box-shadow | box-shadow | 0 10px 28px rgba(24, 24, 27, 0.14) | Shadow of a node while it is dragged. |
--c2-flow__node__skipped--opacity | number | 0.6 | Opacity of the body of a skipped node. |
--c2-flow__node__connect-target--border-color | color | rgb(2, 101, 220) | Border of the node a connection would be made to. |
--c2-flow__node__connect-target--box-shadow | box-shadow | 0 0 0 3px rgba(2, 101, 220, 0.2) | |
--c2-flow__label--font-size | font-size | 14px | |
--c2-flow__label--font-weight | font-weight | 500 | |
--c2-flow__description--font-size | font-size | 12px | Size of the description and the meta value. |
--c2-flow__description--color | color | #71717a | |
--c2-flow__handle--size | pixel | 7px | Diameter of the dots on the sides of a node that edges leave or arrive by. |
--c2-flow__handle--background-color | color | #ffffff | |
--c2-flow__handle--border-color | color | #a1a1aa | |
--c2-flow__edge--color | color | #d4d4d8 | Edge between steps that have not run yet. |
--c2-flow__edge--width | pixel | 1.5px | |
--c2-flow__edge--animation-duration | time | 600ms | One cycle of the active edge's dash animation. |
--c2-flow__edge__done--color | color | #a1a1aa | Edge out of a finished step. |
--c2-flow__edge__active--color | color | rgb(2, 101, 220) | Animated edge into a running or waiting step. |
--c2-flow__edge__failed--color | color | #dc2626 | Edge out of a failed step. |
--c2-flow__edge__highlighted--width | pixel | 2.5px | Edges of the hovered or selected node. |
--c2-flow__edge__draft--color | color | rgb(2, 101, 220) | The edge drawn while a connection is being made. |
--c2-flow__edge__selected--color | color | rgb(2, 101, 220) | Selected edge of an editable flow. |
--c2-flow__edge__selected--width | pixel | 2.5px | |
--c2-flow__arrow--size | pixel | 8px | Length and width of the arrowhead at the target end of every edge. It takes the edge's colour. |
--c2-flow__arrow--display | display | block | none draws the edges without arrowheads. |
--c2-flow__edge-marker--size | pixel | 12px | Height of a crow's-foot end (one, many…); it is 5/3 as long. It takes the edge's colour and width. |
--c2-flow__edge-label--background-color | color | #ffffff | Background of the pill an edge's label is drawn in, so it stays readable over the line and the dot grid. |
--c2-flow__edge-label--color | color | #71717a | |
--c2-flow__edge-label--font-size | font-size | 12px | |
--c2-flow__edge-label--font-weight | font-weight | 500 | |
--c2-flow__edge-label--padding | padding | 1px 8px | |
--c2-flow__edge-label--border | border | 1px solid #e4e4e7 | |
--c2-flow__edge-label--border-radius | border-radius | 999px | |
--c2-flow__marker--display | display | inline-flex | The status marker of the default node body. none hides it and the label sits flush with the padding. |
--c2-flow__success--color | color | #16a34a | |
--c2-flow__error--color | color | #dc2626 | |
--c2-flow__warning--color | color | #d97706 | |
--c2-flow__running--color | color | rgb(2, 101, 220) | |
--c2-flow__current--color | color | rgb(2, 101, 220) | |
--c2-flow__pending--color | color | #a1a1aa | |
--c2-flow__skipped--color | color | #a1a1aa | |
--c2-flow__card--width | pixel | 300px | |
--c2-flow__card--padding | padding | 14px | |
--c2-flow__card--background-color | color | #ffffff | |
--c2-flow__card--color | color | #18181b | |
--c2-flow__card--border | border | 1px solid #e4e4e7 | |
--c2-flow__card--border-radius | border-radius | 8px | |
--c2-flow__card--box-shadow | box-shadow | 0 8px 24px rgba(24, 24, 27, 0.08) | |
--c2-flow__card--font-size | font-size | 14px | |
--c2-flow__card--offset | pixel | 8px | Distance between the node and its hover card. |
--c2-flow__card--transition-duration | time | 150ms | |
--c2-flow__card__term--color | color | #71717a | Labels of the card's detail rows. |
--c2-flow__canvas__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | Focus ring of the empty canvas of an editable flow, the one place that takes focus when there is no node. |
--c2-flow__connector--size | pixel | 12px | Diameter of the connection handles an editable flow shows in the middle of each side of a hovered, focused or selected node. |
--c2-flow__connector--background-color | color | rgb(2, 101, 220) | |
--c2-flow__connector--border-color | color | #ffffff | |
--c2-flow__ghost--border | border | 1.5px dashed rgb(2, 101, 220) | Outline of the placeholder that follows the pointer while dragNewNode() drags a new node onto the canvas. |
--c2-flow__ghost--background-color | color | rgba(2, 101, 220, 0.06) | |
--c2-flow__edge-hit--width | pixel | 12px | Width of the invisible band round an edge that a click selects it by. |
--c2-flow__editor--background-color | color | #ffffff | Inline label editor. |
--c2-flow__editor--color | color | #18181b | |
--c2-flow__editor--border | border | 1px solid #bcbcc6 | |
--c2-flow__editor--border-radius | border-radius | 4px | |
--c2-flow__editor__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | |
--c2-flow__icon--size | pixel | 16px | Size of a node's icon and of a row's. |
--c2-flow__icon--color | color | currentColor | Colour of a node's icon; the node's text colour by default. |
--c2-flow__rows--border-top | border | 1px solid #e4e4e7 | Line between a node's header and its rows. |
--c2-flow__row--min-height | pixel | 32px | |
--c2-flow__row--padding | padding | 0 12px | |
--c2-flow__row--gap | pixel | 8px | Space between a row's icon, label and meta. |
--c2-flow__row--font-family | font-family | — | Font of the rows, e.g. a monospace one for a schema. |
--c2-flow__row--font-size | font-size | 13px | |
--c2-flow__row--border-top | border | 1px solid #f4f4f5 | Line between two rows. |
--c2-flow__row__highlighted--background-color | color | rgba(2, 101, 220, 0.08) | The hovered row and the rows at the far end of its edges, and the row a connection would arrive at. |
--c2-flow__row__moving--background-color | color | rgba(2, 101, 220, 0.12) | The row being moved, by its grip or the keyboard. |
--c2-flow__row-meta--color | color | #71717a | A row's meta, such as a column type. |
--c2-flow__row-meta--font-size | font-size | 12px | |
--c2-flow__row-grip--color | color | #a1a1aa | The grip an editable flow shows on a hovered row, which reorders the rows. |
--c2-flow__row-more--color | color | rgb(2, 101, 220) | The "+ N more" row of a node past its row-limit. |
--c2-flow__row-more--font-size | font-size | 12px | |
--c2-flow__shape--border-color | color | #bcbcc6 | Outline of a diamond, circle or slanted node, and the fold of a note. |
--c2-flow__shape--border-width | pixel | 1px | Width of that outline. |
--c2-flow__shape__diamond--min-height | pixel | 88px | A diamond's least height, so its middle has room for the label. |
--c2-flow__shape__circle--size | pixel | 128px | Width and height of a circle node. |
--c2-flow__shape__note--fold-size | pixel | 14px | Size of a note's folded corner. |
--c2-flow__shape__focus--color | color | rgba(2, 101, 220, 0.6) | Focus ring of a diamond, circle or slanted node, drawn along its outline in place of --c2-flow__node__focus--outline. |
--c2-flow__shape__focus--width | pixel | 2px | How much wider than the outline that ring is. |
Text and languages
The text the component shows, in English. It shows another language when the app adds one with addTranslations, under flow, and the nearest lang asks for it; any message not translated stays in English. {0}, {1}… stand for the values a message carries. Languages guide.
| Key | English | Values |
|---|---|---|
rename | Rename | — |
editLabel | Edit label | — |
delete | Delete | — |
addNode | Add node | — |
zoomIn | Zoom in | — |
zoomOut | Zoom out | — |
fitView | Fit view | — |
layout | Layout | — |
leftToRight | Left to right | — |
topToBottom | Top to bottom | — |
autoLayout | Auto layout | — |
lockLayout | Lock layout | — |
alreadyConnected | {0} is already connected to every other node. | {0} node |
connectPrompt | Connect {0} to {1}. Arrow keys or Tab choose another node, Enter connects, Escape cancels. | {0} source {1} target |
connectTarget | {0}, {1} of {2} | {0} node {1} position {2} total |
connected | Connected {0} to {1}. | {0} source {1} target |
connectionCancelled | Connection cancelled. | — |
edgeSelected | Edge from {0} to {1}, labelled {2}, {3} of {4}, selected. Delete removes it, F2 edits its label. | {0} source {1} target {2} label {3} position {4} total |
noEdges | {0} has no edges. | {0} node |
renameNode | Rename {0} | {0} node |
edgeLabelField | Label of the edge from {0} to {1} | {0} source {1} target |
after | — | {0} items {1} labelled |
before | — | {0} items {1} labelled |
throughRow | {0} through {1} | {0} end {1} row |
rows | — | {0} items |
moreRows | + {0} more | {0} count |
fewerRows | Show fewer | — |
showAllRows | Show all rows | — |
showFewerRows | Show fewer rows | — |
rowsHidden | {0} more rows, Shift+Enter shows them. | {0} count |
rowsShown | All rows of {0} shown. | {0} node |
rowsFolded | Rows of {0} folded. | {0} node |
dragToReorder | Drag to reorder | — |
moveRowUp | Move row up | — |
moveRowDown | Move row down | — |
rowMovePrompt | Reordering the rows of {0}. {1}, {2} of {3}. Up and down arrows pick a row, Alt with an arrow moves it, Enter or Escape ends. | {0} node {1} row {2} position {3} total |
rowPicked | {0}, {1} of {2} | {0} row {1} position {2} total |
rowMoved | {0} moved to {1} of {2}. | {0} row {1} position {2} total |
rowMoveEnded | Done reordering rows. | — |
duration | Duration | — |
dragToConnect | Drag to connect | — |
flowActions | Flow actions | — |
flowMenu | Flow | — |
emptyFlow | Empty flow | — |
emptyHint | Press N or Enter to add a node. | — |
statusPending | Pending | — |
statusCurrent | Waiting | — |
statusRunning | Running | — |
statusSuccess | Succeeded | — |
statusError | Failed | — |
statusWarning | Succeeded with warnings | — |
statusSkipped | Skipped | — |