KQ-1731 · FORK/WIZARD
Fork Wizard
A branching wizard with a map of every step, laid out by depth so forks open and merges close. Choosing an option lights its branch: a dot travels the curve to the next step on springs.glide while the lit stroke draws behind it, every step the choice rules out fades to a dashed ghost, the arriving step's ring lands on springs.recoil, and the count of steps left updates — a range while later forks are still open. The map doubles as navigation with roving focus, answers are kept so going back costs nothing until a choice changes, choice steps are radio cards that say how many steps each leads to, and in a narrow container the map becomes a progress line with a mark at every fork.
Add a sensor
Gaugeworks · Pump house 3
on Connection · mains path
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/fork-wizard
Props
- graph
- ForkWizardGraph
- default defaultForkWizardGraph
- { start, steps } — each step is { id, title, short, body?, kind: "choice" | "field" | "end", options?: { value, label, hint?, next }[], field?: { label, placeholder?, suffix?, required?, validate? }, next? }.
- value / defaultValue
- Record<string, string>
- default — / defaultForkWizardAnswers
- Answers by step id (an option's value or a field's text), controlled or initial; answers off the path are kept.
- onValueChange
- (answers) => void
- default —
- Fires from the choice, keystroke or field that changed an answer.
- step / defaultStep
- string
- default — / the first unanswered step on the path
- The current step's id, controlled or initial.
- onStepChange
- (stepId) => void
- default —
- Fires from Next, Back, the map or the So far trail with the step asked for.
- onChoose
- (stepId, value, answers) => void
- default —
- Fires when an option is chosen — the moment its branch lights.
- onBack
- (fromId, toId) => void
- default —
- Fires when the visitor goes to an earlier step.
- onFinish
- (answers, path) => void
- default —
- Fires from the end step with only the answers on the path and the path's ids.
- mapPosition
- "corner" | "top" | "side"
- default "corner"
- A small card in the corner, a labelled band across the top, or a column at the side with the map running top to bottom.
- density
- "compact" | "regular" | "roomy"
- default "regular"
- Padding, gaps and type size.
- accent
- string
- default "var(--accent-bright)"
- The lit branch, the dot, rings and the primary button — any CSS colour.
- travelDuration
- number
- default 0
- How long the dot takes along a branch, in ms; 0 rides springs.glide.
- title
- string
- default "Add a sensor"
- The wizard's heading.
- subtitle
- string
- default "Gaugeworks · Pump house 3"
- One line under the heading.
- status
- "ready" | "loading" | "error"
- default "ready"
- Loading shows placeholder cards; error explains and offers Try again.
- onRetry
- () => void
- default —
- Try again was pressed after the steps failed to load.
- height
- number
- default 540
- Height of the surface in px; the panel scrolls inside it.
- disabled
- boolean
- default false
- Read only: nothing can be chosen or finished.
- className
- string
- default —
- Classes for the surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| graph | ForkWizardGraph | defaultForkWizardGraph | { start, steps } — each step is { id, title, short, body?, kind: "choice" | "field" | "end", options?: { value, label, hint?, next }[], field?: { label, placeholder?, suffix?, required?, validate? }, next? }. |
| value / defaultValue | Record<string, string> | — / defaultForkWizardAnswers | Answers by step id (an option's value or a field's text), controlled or initial; answers off the path are kept. |
| onValueChange | (answers) => void | — | Fires from the choice, keystroke or field that changed an answer. |
| step / defaultStep | string | — / the first unanswered step on the path | The current step's id, controlled or initial. |
| onStepChange | (stepId) => void | — | Fires from Next, Back, the map or the So far trail with the step asked for. |
| onChoose | (stepId, value, answers) => void | — | Fires when an option is chosen — the moment its branch lights. |
| onBack | (fromId, toId) => void | — | Fires when the visitor goes to an earlier step. |
| onFinish | (answers, path) => void | — | Fires from the end step with only the answers on the path and the path's ids. |
| mapPosition | "corner" | "top" | "side" | "corner" | A small card in the corner, a labelled band across the top, or a column at the side with the map running top to bottom. |
| density | "compact" | "regular" | "roomy" | "regular" | Padding, gaps and type size. |
| accent | string | "var(--accent-bright)" | The lit branch, the dot, rings and the primary button — any CSS colour. |
| travelDuration | number | 0 | How long the dot takes along a branch, in ms; 0 rides springs.glide. |
| title | string | "Add a sensor" | The wizard's heading. |
| subtitle | string | "Gaugeworks · Pump house 3" | One line under the heading. |
| status | "ready" | "loading" | "error" | "ready" | Loading shows placeholder cards; error explains and offers Try again. |
| onRetry | () => void | — | Try again was pressed after the steps failed to load. |
| height | number | 540 | Height of the surface in px; the panel scrolls inside it. |
| disabled | boolean | false | Read only: nothing can be chosen or finished. |
| className | string | — | Classes for the surface. |