Flows and steps
Tours as data, and the five advance rules.
A flow
Steps are data, not components. Reordering a tour is an array edit, and adding one is a single object — no React is written to change a tour.
walkthrough/flows.ts
import { defineFlow } from "@cairnkit/core";
import { anchors } from "./anchors";
export const createQuestions = defineFlow({
id: "create-questions",
version: 1,
entryRoute: "/questions",
steps: [
{
anchor: anchors.questions.tabCreate,
title: "Start a new question",
body: "Pick how you want to write it.",
advanceOn: { type: "click" },
},
],
});The five advance rules
A step ends when the user has actually done the thing, not when a timer expires.
| Prop | Type | Default | Description |
|---|---|---|---|
next | { type: "next" } | — | User presses Next. The default, for explanatory steps. |
click | { type: "click" } | — | User clicks the spotlit element itself. |
route | { type: "route"; pathname } | — | The pathname matches. For steps whose action navigates. |
event | { type: "event"; name } | — | Your app calls emitTourEvent — for async work like a save. |
condition | { type: "condition"; awaitAnchor } | — | Another anchor appears. For conditional branches. |
Step options
| Prop | Type | Default | Description |
|---|---|---|---|
anchorrequired | RegisteredAnchor | — | The element to spotlight. |
mobileAnchor | RegisteredAnchor | — | Used instead below the mobile breakpoint. |
title / body | string | — | Literal copy. |
titleKey / bodyKey | string | — | Resolved through your translate function instead. |
placement | Placement | "bottom" | Where the card sits relative to the target. |
advanceOn | AdvanceRule | { type: "next" } | What satisfies the step. |
optional | boolean | false | Skip silently if the anchor never appears. |
waitForMs | number | 4000 | How long to wait for a missing anchor. |
padding | number | 8 | Spotlight padding around the target. |
beacon | boolean | — | Pulsing dot. Defaults on for click steps. |
Versioning
Bump version whenever you add, remove or reorder steps. Progress is persisted, and the version is what tells Cairn a saved step index is no longer meaningful.