APOLLO VISION LABS

Migrating to 0.3.0

What changes for an application on guide-core 0.2.0 and guide-mui 0.3.0, in order, and the one thing that needs attention.

0.3.0 adds hotspots and lets a step advance on a click of its target, and it fixes a flash in the checklist and hotspot renderers while their initial storage read is in flight. Nothing here breaks at runtime. If you use TypeScript and annotate StepPopoverLabels as a complete object, one thing needs a line added before this typechecks again.

pnpm up @apollovisionlabs/guide-core @apollovisionlabs/guide-mui

guide-core moves from 0.2.0 to 0.3.0 and guide-mui from 0.3.0 to 0.4.0. They ship as a pair, so this page covers both together.

What can be ignored

Tours, checklists and persistence work exactly as before. Tour, Step, GuideProvider, GuideTour, useTour, useGuideStep, Checklist, ChecklistProvider, ChecklistLauncher, useChecklist, GuideStorage, createMemoryStorage and createBrowserStorage are all unchanged. The tour and checklist events are unchanged, and the two new hotspot events are additions to the GuideEvent union, not replacements.

Hotspots are opt in. Not mounting HotspotProvider leaves your application exactly where it was.

The one thing to check: StepPopoverLabels gained a required member

StepPopoverLabels, exported from @apollovisionlabs/guide-mui, gained a required member, awaitingAction: the text shown in place of the Next button while a step waits for the user to click its target, through the new advanceOn: 'click'.

interface StepPopoverLabels {
  next: string;
  previous: string;
  finish: string;
  close: string;
  awaitingAction: string; // new, required
}

GuideTour’s labels prop is a Partial<StepPopoverLabels>, so passing labels inline is unaffected either way:

// Still compiles, still works, nothing to change.
<GuideTour labels={{ next: 'Suivant', previous: 'Retour' }} />

What stops typechecking is a constant annotated as a complete StepPopoverLabels:

// Before 0.3.0, this compiled.
const labels: StepPopoverLabels = {
  next: 'Suivant',
  previous: 'Retour',
  finish: 'Terminer',
  close: 'Fermer',
};

Add the new member and it typechecks again:

const labels: StepPopoverLabels = {
  next: 'Suivant',
  previous: 'Retour',
  finish: 'Terminer',
  close: 'Fermer',
  awaitingAction: 'Cliquez sur l’élément mis en évidence pour continuer.',
};

Nothing about this changes behaviour at runtime: a project that never sets advanceOn on any step never renders the text, and a project that passes labels as a Partial was never asked to supply it. This is a source-level change for one specific pattern, not a breaking change to the published API.

Behaviour change: checklists and hotspots wait for their initial storage read

ChecklistProvider and HotspotProvider read persisted progress from storage asynchronously. Before 0.3.0, Checklist, ChecklistLauncher and any custom renderer drew from the initial empty state while that read was still in flight, so a checklist you had dismissed long ago could flash its launcher on screen before vanishing, and a checklist with three of four items done could render “0 of 4” before jumping to “3 of 4”, on every page load.

useChecklist gains a restored member, settled per checklist: true immediately when no storage prop was given, and true once that checklist’s own read resolves or rejects otherwise. useHotspots gains the same restored member, settled once for the whole provider on the same terms. Checklist, ChecklistLauncher and Hotspots all wait for it before drawing anything.

The one user-visible effect: with a slow storage backend, a checklist or a hotspot marker now appears slightly later than it used to, rather than appearing at once and then jumping or flashing a stale state. Nothing to change in your code either way, unless you built your own renderer on useChecklist or useHotspots and want it to wait for restored too.

In order

  1. Bump both packages to their current versions.
  2. If you annotate a StepPopoverLabels constant in full rather than passing labels inline, add awaitingAction. Typecheck: nothing else in either package’s public types changed.
  3. Optionally, add hotspots. HotspotProvider and Hotspots are new, and HotspotProvider can share the storage instance you already pass to GuideProvider and ChecklistProvider.