← All @molecule/* packages · App templates
@molecule/app-tourCore interface · tour · App (browser) · v1.0.1 · Apache-2.0
Tour core interface for molecule.dev.
npm install @molecule/app-tour@molecule/app-tour is the tour core interface on the app (browser) side: the API your app calls, with no vendor inside.
Choose the implementation by bonding one of its 1 provider: @molecule/app-tour-shepherd.
import { requireProvider, setProvider } from '@molecule/app-tour'
import { provider } from '@molecule/app-tour-shepherd'
setProvider(provider) // once, at startup (bonds.ts)
const tour = requireProvider().createTour({
steps: [
{
target: '[data-mol-id="editor"]',
title: 'Editor',
content: 'Write code here',
action: () => renderTourStep(tour.getCurrentStep()),
},
],
onComplete: () => markTourSeen(),
})
tour.start()Providers (1): @molecule/app-tour-shepherd
Works with: @molecule/app-bond
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Tour core interface for molecule.dev.
Provides a standardized API for onboarding walkthrough and guided
tour UI components. Bond a provider (e.g. @molecule/app-tour-shepherd)
to supply the concrete implementation.
import { requireProvider, setProvider } from '@molecule/app-tour'
import { provider } from '@molecule/app-tour-shepherd'
setProvider(provider) // once, at startup (bonds.ts)
const tour = requireProvider().createTour({
steps: [
{
target: '[data-mol-id="editor"]',
title: 'Editor',
content: 'Write code here',
action: () => renderTourStep(tour.getCurrentStep()),
},
],
onComplete: () => markTourSeen(),
})
tour.start()
core
npm install @molecule/app-tour @molecule/app-bond
TourInstanceA live tour instance returned by the provider.
interface TourInstance {
/**
* Starts the tour from the beginning.
*/
start(): void
/**
* Advances to the next step.
*/
next(): void
/**
* Goes back to the previous step.
*/
previous(): void
/**
* Cancels the tour without completing it.
*/
cancel(): void
/**
* Marks the tour as complete and triggers the onComplete callback.
*/
complete(): void
/**
* Checks whether the tour is currently running.
*
* @returns `true` if the tour is active.
*/
isActive(): boolean
/**
* Returns the index of the current step.
*
* @returns Zero-based index of the current step.
*/
getCurrentStep(): number
/**
* Whether a backdrop overlay should be rendered for this tour.
*
* The provider tracks state only and draws nothing on screen — read this in
* your render code to decide whether to paint the backdrop. Reflects the
* resolved `overlay` value: the per-tour {@link TourOptions.overlay}, else
* the provider's default, else `true`.
*
* @returns `true` if the consumer should render a backdrop overlay.
*/
hasOverlay(): boolean
/**
* Whether navigation buttons (back / next / done) should be rendered.
*
* The provider draws no buttons itself — read this in your render code to
* decide whether to paint the nav controls. Reflects the resolved
* `showButtons` value: the per-tour {@link TourOptions.showButtons}, else the
* provider's default, else `true`.
*
* @returns `true` if the consumer should render navigation buttons.
*/
hasButtons(): boolean
}
TourOptionsConfiguration options for creating a tour.
interface TourOptions {
/** Steps to display in the tour. */
steps: TourStep[]
/** Callback when the tour is completed. */
onComplete?: () => void
/** Callback when the tour is cancelled. */
onCancel?: () => void
/** Whether to show a progress indicator. Defaults to `true`. */
showProgress?: boolean
/**
* Whether navigation buttons (back / next / done) should be rendered.
* Defaults to `true`. Surfaced back to the consumer's render code via
* {@link TourInstance.hasButtons}.
*/
showButtons?: boolean
/**
* Whether a backdrop overlay should be rendered. Defaults to `true`.
* Surfaced back to the consumer's render code via
* {@link TourInstance.hasOverlay}.
*/
overlay?: boolean
}
TourProviderTour provider interface.
All tour providers must implement this interface to create and manage onboarding walkthrough / guided tour UI.
interface TourProvider {
/** Provider name identifier. */
readonly name: string
/**
* Creates a new tour instance.
*
* @param options - Configuration for the tour.
* @returns A tour instance for controlling the walkthrough.
*/
createTour(options: TourOptions): TourInstance
}
TourStepA single step in a guided tour.
interface TourStep {
/** CSS selector for the target element to highlight. */
target: string
/** Title of the tour step. */
title: string
/** Content/description body for the step. */
content: string
/** Preferred placement of the tooltip relative to the target. */
placement?: 'top' | 'bottom' | 'left' | 'right'
/** Action to perform when the step is shown. */
action?: () => void
/** Async function that runs before the step is displayed. */
beforeShow?: () => Promise<void>
}
getProvider()Retrieves the bonded tour provider, or null if none is bonded.
function getProvider(): TourProvider | null
Returns: The active tour provider, or null.
hasProvider()Checks whether a tour provider has been bonded.
function hasProvider(): boolean
Returns: true if a tour provider is available.
requireProvider()Retrieves the bonded tour provider, throwing if none is configured.
function requireProvider(): TourProvider
Returns: The active tour provider.
setProvider(provider)Registers a tour provider as the active singleton.
function setProvider(provider: TourProvider): void
provider — The tour provider implementation to bond.| Provider | Package |
|---|---|
| Tour | @molecule/app-tour-shepherd |
Peer dependencies:
@molecule/app-bond ^1.0.1@molecule/app-bond
The provider manages tour STATE — it does not draw the overlay. The
bundled bond tracks the active step and fires each step's action plus
onComplete/onCancel; the highlight/tooltip UI is the consumer's to
render from getCurrentStep() and the step's target/title/content.
Don't expect start() alone to put anything on screen.
Read the overlay/showButtons intent back off the instance. Because
the provider draws nothing, TourOptions.overlay/showButtons are surfaced
for the consumer via hasOverlay()/hasButtons() (resolved: per-tour
option → provider default → true). Gate the backdrop and nav buttons your
render code paints on those accessors rather than re-deriving the flags.
The instance has NO change subscription — drive re-renders from the
per-step action callbacks (or wrap next/previous), not by polling.
target is a CSS selector: prefer stable [data-mol-id="…"] selectors
over styling class names (class strings are ClassMap-bond-owned and
swappable).
Step title/content are UI text — source them via
t('key', values, { defaultValue }), and style the rendered tour UI with
getClassMap() from @molecule/app-ui.
Wire it with THIS package's setProvider() or bond('tour', …).
setProvider() delegates into the shared @molecule/app-bond registry, so
both write the same slot; {@link requireProvider} throws until one has run.
Integration checklist — drive the real UI (live preview, no mocks), adapt
each item to this app's actual onboarding flow, and check every box off one
by one. A box you can't check is an integration bug to fix — not a skip. The
provider only tracks state, so every checkpoint is about the overlay the app
RENDERS from getCurrentStep() — verify what's on screen, not just the calls:
title/content)
anchored to that step's target element, with the target highlighted /
spotlighted. start() alone paints nothing — the per-step action is what
draws the overlay, so confirm the anchored tooltip actually appears.next advances in order: the tooltip + highlight move to each step's
target and the progress indicator updates (e.g. "2 of 5" — getCurrentStep()
is zero-based, so it reads step+1 of steps.length). previous moves one
step back. next on the LAST step does not wrap or auto-finish (the bond
no-ops past the end), so a visible Done/Finish control must call complete().cancel()) ends the tour immediately — the overlay and
tooltip disappear, isActive() is false — and fires onCancel.onComplete and closes the tour (overlay
and tooltip gone, isActive() false).onComplete/onCancel
and gate start() on it; verify the persistence survives a reload.target selector matches no element is handled gracefully
(the step is skipped or the tour ends) — it never crashes anchoring a tooltip
to a null element (the bond keeps target as a plain string and never
touches the DOM, so this guard lives in the app's render code).overlay on (i.e. hasOverlay() is
true), the backdrop blocks interaction outside the current step — clicks
reach only the tour controls and the highlighted target; ending the tour
restores normal interaction. A tour created with overlay: false reports
hasOverlay() === false and your render code paints no backdrop. Likewise
gate the nav buttons on hasButtons().