5.7 KiB
5.7 KiB
Tasks: enterprise-browser-react-tour
Change ID: enterprise-browser-react-tour
Package: @suaveplan/react-tour
Target path: browser/react/react-tour
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/events, @suaveplan/logger, @suaveplan/schema-registry
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree per
proposal.md. package.jsonv0.0.0,"sideEffects": false.dependencies:@suaveplan/error workspace:^,@suaveplan/events workspace:^,@suaveplan/logger workspace:^,@suaveplan/schema-registry workspace:^,zod catalog:forms,@opentelemetry/api catalog:observability,tslib catalog:build,react catalog:reactpeerDependencies:reactdevDependencies:vitest catalog:testing,@vitest/coverage-istanbul catalog:testing,happy-dom catalog:testing,@testing-library/react catalog:testing,@suaveplan/testing workspace:^,@suaveplan/testing-dom workspace:^- Subpath exports:
".","./core/tour/tour","./utils/positioning","./persistence"
tsconfig.json,vitest.config.ts(pool: forks, happy-dom environment).
2. Error codes
TOUR_CONFIG_INVALID,TOUR_STEP_NOT_FOUND.registerTourErrorCodes()— call eagerly.
3. Types (src/types/common.ts)
TourConfig,TourStep,TourState,TourActions,TooltipPlacement,TooltipPosition,SpotlightInset.- Write
common.md.
4. TourSchema (src/schema/tour-schema/)
tour-schema.ts—TourConfigSchema,TourStepSchema(Zod);registerTourSchemas().- Write
tour-schema.md.
5. Positioning utilities (src/utils/positioning/)
positioning.ts—calculateSpotlightInset,calculateTooltipPosition,getTargetRect,scrollTargetIntoView.- All functions SSR-safe (
typeof documentguard). - Write
positioning.test.ts(happy-dom geometry, SSR import smoke test). Writepositioning.md.
6. Observer utility (src/utils/observe-target/)
observe-target.ts— compositeobserveTarget(selector, callback)usingResizeObserver+IntersectionObserver+ scroll listener; returns cleanup.- Write
observe-target.test.ts(observer fires on resize, fires on scroll). Writeobserve-target.md.
7. Persistence adapters (src/persistence/persistence/)
persistence.ts—PersistenceAdapterinterface;LocalStoragePersistence(SSR-safe),SessionStoragePersistence,MemoryPersistence.- Write
persistence.test.ts(each adapter: isCompleted, markCompleted, clear, SSR no-throw). Writepersistence.md.
8. Tour state helpers (src/core/tour/tour-state.ts)
computeProgress(step, total): number, boundary guards,shouldSkipevaluation.
9. Tour effects (src/core/tour/tour-effects.ts)
- Observer wiring: call
observeTargeton step change, updatetargetRecton callback. - Emit
@suaveplan/eventslifecycle events (tour:start,tour:step-change,tour:complete,tour:skip,tour:error). - Wire OTel metrics.
10. Tour actions (src/core/tour/tour-actions.ts)
next(),prev(),goTo(n),skip(),reset()— with boundary checks andshouldSkipevaluation.
11. useTour hook (src/core/tour/tour.ts)
- Compose state + effects + actions.
- Validate
TourConfigviaTourConfigSchemaon entry; throwTOUR_CONFIG_INVALID. - Log storage errors via
@suaveplan/loggerinstead of swallowing. - Write
tour.test.ts(config validation, next/prev/goTo/skip, persistence, SSR no-throw). Writetour.md.
12. Storybook stories (src/stories/use-tour.stories.tsx)
- Default story: basic 3-step tour.
- Spotlight overlay: CSS spotlight with
calculateSpotlightInset. - Scroll-into-view: target below the fold.
- Completion persistence: reload and confirm tour does not restart.
- Accessibility-compliant tooltip:
role="dialog", focus trap,aria-live.
13. Integration test (tests/integration.test.ts)
- Full tour flow: start, navigate, complete, verify persistence adapter called.
MemoryPersistenceswap: nolocalStoragetouched.shouldSkipstep evaluated; step skipped automatically.
14. Playwright E2E (e2e/react-tour.spec.ts)
targetRectstays aligned after element resizes (Playwright + Chromium).- Completion persists across reload (Playwright localStorage).
- SSR smoke: import from Node without throwing.
15. Docs + verify
- Write
.mdper module (≥200 words, API reference, examples). - Write
README.mdwith subpath table, persistence-adapter guide, SSR guide, a11y notes. bunx turbo lint typecheck test --filter=@suaveplan/react-tour— green.bunx turbo test:coverage— 100%.- No
@ts-expect-errorinsrc/or tests. Novi.stubGlobal. - Storybook stories render and pass axe-core.
- Playwright E2E green on Chromium.
bun scripts/publish.ts --package @suaveplan/react-tour.- Archive to
openspec/archive/2026-04-24-enterprise-browser-react-tour/.