feat: Tour / product-tour (NUX) pattern — intro modal + spotlight feature steps + workflow steps (research & design)
- Dominant language
- TypeScript
- Stars
- 13.1k
- Forks
- 1.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 687
Description
## Summary
Astryx has no **Tour / product-tour (NUX/onboarding)** pattern. This is a common need — guided introductions and feature walkthroughs that highlight parts of the UI and step a user through them. An internal design system has a mature version of this that we should research and port the *value/behavior* of (not the internal structure). This issue is to **research and design** the pattern before any build — it's a multi-surface component family that needs a proper spec.
## The pattern (three surfaces)
Based on prior art, a Tour is a coordinated experience with a controller and a few step/surface types:
1. **Intro modal** — a centered dialog that opens the tour, with a heading, description, primary/secondary actions ("Start tour" / "Skip"), and an optional **media slot** (illustration/image/video) — i.e. a modal variant with and without media.
2. **Spotlight / feature step** — highlights a specific target element on the page (a "spotlight" cutout / emphasized target with a dimmed surround) and renders a positioned callout anchored to it, with title, body, step progress ("2 of 5"), and next/back/close controls.
3. **Workflow step** — steps that guide the user through an actual multi-step task/flow (as opposed to just pointing at features).
A **controller** manages the whole thing: an `isActive` state, start/dismiss/complete callbacks, current-step tracking, and advancing/retreating between steps. (Prior art exposes a tour controller plus separate intro-modal, feature-step, and workflow-step pieces.)
## Why it needs research + design (spec-track)
This is a component *family*, not a single component, and it leans on infrastructure we already have — so the design must decide how to compose rather than reinvent:
- **Spotlight/anchoring:** highlighting a target + positioning a callout is a layer/anchoring problem — reuse the existing `Popover`/`Layer`/`useLayer` anchoring (and `Dialog`/scrim for the dim). Research whether we can express the spotlight cutout with the current layer system.
- **Intro modal:** should compose the existing `Dialog` (and the hero-header work, #4182) rather than a bespoke modal. The media vs no-media variants map onto Dialog + a media slot.
- **Controller/state:** how is tour state owned — a context + hook (`useTour`) driving `isActive`/current step, with steps registered declaratively? Follow the system's "hooks over wrappers" and controlled/uncontrolled conventions.
- **Step targeting:** how does a step reference its target element (ref, id, selector)? a11y of moving focus between steps, `aria`-describedby of the callout, Escape-to-dismiss, focus return.
- **Persistence/dismissal** (has-seen-this-tour) is app state — the component should expose callbacks, not own storage.
## Research inputs
- Port the *value and behavior* of the internal tour system (controller + intro modal + spotlight feature step + workflow step) — NOT its internal structure or naming. Describe patterns/conclusions, not internal component names, in the public spec.
- Screenshots of the internal + prior-art versions (intro modal with/without media, spotlight feature steps with progress, workflow steps) are the design reference — attach/summarize in the spec.
- Compare external prior art: Shepherd.js, Reactour, Intro.js, Radix (no built-in), driver.js — anchoring model, step API (array vs declarative children), spotlight technique, a11y handling.
## Scope of this issue
Research + a specification (9-phase) covering: the surface set (intro modal / spotlight step / workflow step), the controller/state model, how each surface composes existing Astryx primitives (Dialog, Popover/Layer, hero header), the step-targeting + a11y model, and the public API. No build until the spec is reviewed. Likely lands in `lab` first given the size.
## Acceptance (of the design phase)
- A spec proposing the Tour component family + controller, grounded in composition of existing primitives, with the step API, spotlight/anchoring approach, and a11y model decided; reviewed before build.
Contributor guide
Research direction
Start by reviewing the existing Dialog, Popover/Layer, and useLayer primitives, plus the hero-header work in #4182. Compare the listed internal and external tour references, then produce the requested 9-phase specification covering the surface family, controller, composition, targeting, accessibility, and public API; done means the spec is reviewed before any build.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- accessibility, design, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100