Several short stories
A tour is several short stories rather than one long one. A story runs forward
from its first step and cannot be entered anywhere else, so a user who wants to
go back runs it again, and a short story is quick to run again. A story names
the one that follows it in next, and a branch is a next that chooses
between stories.
A story runs forward from its first step
Section titled “A story runs forward from its first step”start() shows a story from its first step, and nothing takes a tour back to a
step it has left. A step that declares awaits waited for something the
application reports once, so a tour put back on it would wait for ever —
A story is atomic, and stories are short.
- A step without
awaitsgets no back control either.onLeavecan close a panel again but cannot unsave an order, and a back control that worked on some steps and not others would be worse than none — A story is atomic, and stories are short. - Nothing on the instance takes a tour back, or into a story part-way through. The calls an application makes are the four under Methods.
- Going back is running the story again.
stop()ends the story that is running, andstart()then begins it, or another story, at its first step. Astart()alone, while a tour runs, is refused — start. - Split a story before it grows long. A story of four steps costs a few seconds to run again, and a story of twenty is where a back control starts to feel necessary — A story is atomic, and stories are short.
next joins one story to the one after it
Section titled “next joins one story to the one after it”A story names the story that follows it in next, and when its last step moves
on, the tour goes on into that story from its first step. Here careful, one
way through reviewing an order, hands on to summary.
import type { LekoStory } from '@annetaan/leko'
export const summary = { id: 'summary', steps: [{ id: 'summary', target: '#status', message: 'The order is on its way.' }],} satisfies LekoStory
export const careful = { id: 'careful', steps: [ { id: 'lines', target: [{ elements: '#check', interactive: true }, '#lines'], message: 'Check each line of the order, then tick the box.', awaits: 'lines-checked', }, { id: 'send', target: { elements: '#send', interactive: true }, message: 'Send the order.', awaits: 'order-sent', }, ], next: summary,} satisfies LekoStory- Only a story that ran to its last step is followed. A user who closes
the tour in
carefulis not taken intosummary. What else ends a tour without askingnextis under next. - The story that finished can leave its setup in place. Its
onLeaveis handed the story that follows, so teardown that story would rebuild can be skipped — story.onLeave. - The count starts again with each story.
indexcounts the steps of the story that is running, so a count across the whole tour is the application’s own sum. nextalso carries a tour across a link that loads a new page — A story hands its next to the new page, and pickUp starts it.
A branch is a next that chooses
Section titled “A branch is a next that chooses”A next may be a function, and the story it answers with is the one that
runs. The branch below is three kinds of story: one that asks the user to choose,
one for each way on, and one where the ways meet. Here the ways meet at the
summary above, which careful and quick both name as their next. What
two paths share is a story rather than a step they both point at, so no branch
has to know how many steps came before it —
A story is atomic, and stories are short.
// src/stories.ts, below summary and carefulexport const quick = { id: 'quick', steps: [ { id: 'send', target: { elements: '#send', interactive: true }, message: 'Send the order.', awaits: 'order-sent', }, ], next: summary,} satisfies LekoStory
export const intro = { id: 'intro', steps: [ { id: 'choose', target: { elements: ['#careful', '#quick'], interactive: true }, message: 'Check every line first, or send the order now.', awaits: 'path-chosen', }, ], next: () => (order.path === 'careful' ? careful : quick),} satisfies LekoStoryorder is your application’s own, and records which button was pressed.
- The step that asks for the choice declares
awaits. The application reportspath-chosenonce it has recorded the choice, andnextreads the choice from there. nextis asked again on every run, so a second run ofintrodoes not inherit the first run’s branch.
The application may also choose the story it hands start(), such as one story
for a wide window and another for a narrow one.
See it run
Section titled “See it run”The example A tour that branches is these four
stories on markup of its own, with a first step in intro that lights the
order’s total. On the careful way, the footer reads careful 1/2, and
summary 1/1 once the order is sent. Closing the tour on either branch ends it
there, and the summary never shows.
The Playground chooses the story it
starts by the window’s width. When the width crosses while its first story
shows, it calls stop() and starts the story for the new width.