⬡ FRAMEWERK
Core

Flows

Flows record navigation edges between screens — documentation of intent and the input to reachability analysis, not the navigation mechanism; a timed link carries its delay.

View as Markdown

Flows

Flows record navigation edges between screens: documentation of intent and the input to reachability analysis — navigate() works whether or not an edge is declared.

Examples

A single edge:

One flow edge
phone
SPEC.JSON
RENDERED OUTPUTFRAMEWERK RENDERER
Menu
Order
Edit the JSON to update the rendered screen.Edits stay in this preview

An edge with transition metadata:

A modal transition
phone
SPEC.JSON
RENDERED OUTPUTFRAMEWERK RENDERER
Inbox
Compose
Edit the JSON to update the rendered screen.Edits stay in this preview

Anatomy

{ "flows": [{ "from": "menu", "to": "order", "trigger": "Order button" }] }

Flows are documentation of intent, not the navigation mechanism — their value is analysis: the validator uses reachability to flag orphaned screens, and flows are what render as a map of the app.

A flow may carry transition metadata that animates the swap in playback:

{ "from": "inbox", "to": "compose", "type": "modal",
  "transition": { "name": "fade", "duration": 300 } }

Names: slide-left, slide-right, slide-up, slide-down and fade move only the incoming screen; push-left, push-right, push-up, push-down move both like a navigation stack; dissolve cross-fades both; shared morphs every node whose style.viewTransitionName matches on both screens (View Transitions API, dissolve where it is missing); none suppresses a default. easing takes any CSS curve or spring(mass, stiffness, damping).

Omitted metadata falls back to the flow type: modal presents as a sheet slide-up above the current screen, which stays mounted beneath a scrim (overlay: false takes the whole frame; dim sets the scrim, closeOnOutside makes the scrim navigate the reverse flow), dismiss animates the outgoing screen away (slide-down by default — the transition name on a dismiss flow describes how the departing screen leaves), and navigate/replace stay instant unless opted in.

A link that follows on its own after a wait carries "trigger": "timeout" and delay, the wait in milliseconds, so the map can draw it: { "from": "splash", "to": "home", "trigger": "timeout", "delay": 800 }. The flow only records it; the source screen's onEnter is what plays it.

flowPackages group multi-step journeys (onboarding, checkout) into named sequences with per-step context.

Stability

Flow fields (from, to, trigger, delay, type, transition) and the transition-name set are part of the format contract. Adding a transition name is additive; changing how an existing one animates is breaking.