React bindings for Flowsterix - guided tours and onboarding flows
npm install @flowsterix/reactThis is the maintainer-facing source of truth for @flowsterix/react.
It covers:
- package concepts and architecture
- runtime data flows and state transitions
- capability coverage map
- exhaustive API inventory (main entry and subpath exports)
- test and release maintenance workflow
It is intentionally implementation-oriented and not end-user onboarding docs.
- package root: packages/react
- primary source entry: src/index.tsx
- published outputs: dist/*
- package exports:
- @flowsterix/react
- @flowsterix/react/router
- @flowsterix/react/router/tanstack
- @flowsterix/react/router/react-router
- @flowsterix/react/router/next-app
- @flowsterix/react/router/next-pages
- @flowsterix/react/devtools
@flowsterix/react is a React runtime around core flow state (@flowsterix/core) plus UI primitives and integration helpers.
Core concepts:
- Flow runtime:
- Active flow and active step are sourced from the core store and exposed by TourProvider.
- Target resolution:
- Step targets are resolved to element + rect snapshots (useTourTarget) with rectSource provenance.
- HUD composition:
- useHudState and useTourHud derive renderability, fallback strategy, lock behavior, and UX metadata.
- Overlay and popover:
- useTourOverlay computes cutout geometry.
- OverlayBackdrop and TourPopoverPortal render visual primitives and transition behavior.
- Cross-step handoff:
- Overlay and popover preserve cached position during resolving windows and promote to live rect on gating conditions.
- Motion strategy:
- Motion can run as spring/tween/reduced via adapter abstraction.
- Router gating:
- Route signals can pause/resume or advance flows through route-aware hooks and adapters.
``mermaid`
flowchart TD
A["TourProvider
(src/context.tsx)"] --> B["useTourTarget
(resolve rect, scroll, source)"]
A --> C["useHudState
(step render state, fallback)"]
B --> C
C --> D["useTourHud
(HUD behavior + lock)"]
C --> E["useTourOverlay
(mask geometry + handoff gate)"]
D --> F["TourPopoverPortal
(position + handoff gate)"]
E --> G["OverlayBackdrop"]
D --> H["TourFocusManager"]
1. TourProvider exposes activeFlowId, activeStep, state.useTourTarget
2. resolves target:rectSource
- selector/getNode/screen resolution
- viewport/observer/raf updates
- assignment (none|live|stored|viewport)useHudState
- step-enter scroll and auto-scroll safeguards
3. combines flow state and target state:useHiddenTargetFallback
- route mismatch handling
- hidden/missing fallback via useTourHud
- grace-period behavior and render gating
4. derives:
- overlay config
- popover config
- body scroll lock + constrained mode
Problem:
- During cross-step smooth scroll, live rect can be in transient positions.
- Immediate promotion causes visual jumps or settle artifacts.
Solution:
- Keep cached previous rect during handoff.
- Promote to live when:
- visibility gate passes (fitted vs oversized thresholds)
- and motion gate passes:
- settle-by-time, or
- settle-by-speed
Current handoff logic is implemented in:
- src/hooks/useTourOverlay.tssrc/components/TourPopoverPortal.tsx
-
Both should stay aligned unless divergence is deliberate.
- Normal lock path: useBodyScrollLockuseConstrainedScrollLock
- Oversized target path: scrollMargin.ts
- Margin semantics: useTourTarget.ts
- Target auto-scroll entry + redispatch safeguards:
| Capability | Primary APIs | Implementation |
| --- | --- | --- |
| Flow runtime provider | TourProvider, useTour, useTourEvents | src/context.tsx |defaultLabels
| Labels/i18n surface | , useTourLabels | src/labels.ts |useTourTarget
| Target acquisition and rect provenance | | src/hooks/useTourTarget.ts |useHudState
| HUD state derivation | , useTourHud | src/hooks/useHudState.ts, src/hooks/useTourHud.ts |useHiddenTargetFallback
| Hidden/missing fallback handling | | src/hooks/useHiddenTargetFallback.ts |useTourOverlay
| Overlay geometry and mask state | , OverlayBackdrop | src/hooks/useTourOverlay.ts, src/components/OverlayBackdrop.tsx |TourPopoverPortal
| Popover positioning modes and persistence | | src/components/TourPopoverPortal.tsx |useTourFocusDominance
| Focus dominance and trap management | , TourFocusManager | src/hooks/useTourFocusDominance.ts, src/components/TourFocusManager.tsx |useTourControls
| Tour controls state | | src/hooks/useTourControls.ts |useDelayAdvance
| Delay progress | | src/hooks/useDelayAdvance.ts |useHudMotion
| Motion abstraction and strategy | adapter exports + | src/motion/* |useBodyScrollLock
| Body lock and constrained lock | , useConstrainedScrollLock | src/hooks/useBodyScrollLock.ts, src/hooks/useConstrainedScrollLock.ts |getCurrentRoutePath
| Route channel and matching | , notifyRouteChange, subscribeToRouteChanges, createPathString, matchRoute | src/router/routeGating.ts, src/router/utils.ts |src/router/*Adapter.tsx
| Framework router adapters | router subpath hooks/components | , src/router/tanstackRouterSync.tsx |useRadixDialogAdapter
| Radix dialog integration | , useRadixTourDialog, registry exports | src/adapters/radixDialog.ts, src/hooks/useRadixTourDialog.ts, src/dialog/DialogRegistryContext.tsx |@flowsterix/react/devtools
| DevTools surface | exports | src/devtools/* |
This section is intended to cover every exported identifier in source.
#### Runtime exports
- Core runtime:
- TourProvideruseTour
- useTourEvents
- defaultLabels
- Labels:
- useTourLabels
- useTourTarget
- Target and HUD hooks:
- useHudState
- useHudDescription
- useHudShortcuts
- useTourHud
- useTourOverlay
- useHudTargetIssue
- useRadixDialogAdapter
- Dialog and registry:
- waitForDom
- useRadixTourDialog
- DialogRegistryProvider
- useDialogRegistry
- useDialogRegistryOptional
- useTourFocusDominance
- Focus and controls:
- useTourControls
- useDelayAdvance
- OverlayBackdrop
- Components:
- TourPopoverPortal
- TourFocusManager
- AnimationAdapterProvider
- Motion:
- defaultAnimationAdapter
- reducedMotionAnimationAdapter
- tweenAnimationAdapter
- useAnimationAdapter
- usePreferredAnimationAdapter
- useHudMotion
- useAdvanceRules
- Low-level hooks/utilities:
- useBodyScrollLock
- useConstrainedScrollLock
- useHiddenTargetFallback
- useViewportRect
- createWaitForPredicateController
- getCurrentRoutePath
- Router utility exports (main entry safe subset):
- notifyRouteChange
- subscribeToRouteChanges
- createPathString
-
#### Type exports
- Context/provider:
- DelayAdvanceInfoTourContextValue
- TourProviderProps
- TourLabels
- Labels:
- TourTargetInfo
- Target:
- UseHudStateOptions
- HUD state and hooks:
- UseHudStateResult
- UseHudDescriptionOptions
- UseHudDescriptionResult
- UseHudShortcutsOptions
- TourHudDescription
- TourHudFocusManagerState
- TourHudOverlayConfig
- TourHudPopoverConfig
- UseTourHudOptions
- UseTourHudResult
- HudTargetIssue
- UseHudTargetIssueOptions
- UseHudTargetIssueResult
- TourOverlayRect
- Overlay and popover:
- TourOverlaySegment
- UseTourOverlayOptions
- UseTourOverlayResult
- OverlayBackdropProps
- OverlayBackdropTransitionsOverride
- TourPopoverLayoutMode
- TourPopoverPortalProps
- TourPopoverPortalRenderProps
- TourFocusManagerProps
- RadixDialogAdapterResult
- Dialog:
- UseRadixDialogAdapterOptions
- UseRadixTourDialogParams
- UseRadixTourDialogResult
- DialogController
- DialogRegistryContextValue
- UseTourFocusDominanceOptions
- Focus, controls, delay:
- UseTourFocusDominanceResult
- TourControlsState
- DelayAdvanceProgress
- AnimationAdapter
- Motion:
- AnimationAdapterComponents
- AnimationAdapterProviderProps
- AnimationAdapterTransitions
- UseAnimationAdapterOptions
- UseHudMotionResult
- ConstrainedScrollLockOptions
- Scroll/fallback/predicate:
- UseHiddenTargetFallbackConfig
- UseHiddenTargetFallbackResult
- WaitForPredicateController
- WaitForPredicateControllerOptions
-
Runtime exports:
- getCurrentRoutePathmatchRoute
- notifyRouteChange
- routeGatingChannel
- subscribeToRouteChanges
- createPathString
-
Runtime exports:
- useTanStackRouterTourAdaptergetTanStackRouter
- getTourRouter
- setTanStackRouter
- setTourRouter
- TanStackRouterSync
-
Type exports:
- TanStackRouterSyncProps
Runtime exports:
- useReactRouterTourAdapter
Runtime exports:
- useNextAppRouterTourAdapter
Runtime exports:
- useNextPagesRouterTourAdapter
Runtime exports:
- Provider/context:
- DevToolsProviderDevToolsContext
- useDevToolsContext
- useDevToolsContextRequired
- GrabberOverlay
- Components:
- StepList
- SortableStepItem
- StepItem
- StepItemDragPreview
- Toolbar
- TabNav
- FlowsTab
- FlowItem
- FlowEditModal
- useGrabMode
- Hooks:
- useStepStore
- useElementInfo
- useFlowsData
- generateSelector
- Utilities:
- extractSource
- extractComponentHierarchy
- formatSourcePath
- getVSCodeLink
- loadSteps
- saveSteps
- clearSteps
-
Type exports:
- Provider/context:
- DevToolsProviderPropsDevToolsContextValue
- FlowStorageEntry
- GrabberOverlayProps
- Components:
- StepListProps
- StepItemProps
- StepItemDragPreviewProps
- ToolbarProps
- TabNavProps
- FlowsTabProps
- FlowItemProps
- FlowEditModalProps
- UseGrabModeResult
- Hooks/data:
- UseStepStoreResult
- FlowData
- UseFlowsDataResult
- DevToolsExport
- Types:
- DevToolsState
- DevToolsTab
- ElementInfo
- ElementSource
- GrabbedStep
- GrabMode
-
- Provider and runtime contract:
- src/context.tsxsrc/index.tsx
- src/labels.ts
- Labels:
- src/hooks/useHudState.ts
- HUD and render primitives:
- src/hooks/useTourHud.ts
- src/hooks/useTourOverlay.ts
- src/components/OverlayBackdrop.tsx
- src/components/TourPopoverPortal.tsx
- src/components/TourFocusManager.tsx
- src/hooks/useTourTarget.ts
- Target and scroll mechanics:
- src/hooks/useBodyScrollLock.ts
- src/hooks/useConstrainedScrollLock.ts
- src/hooks/scrollMargin.ts
- src/adapters/radixDialog.ts
- Dialog integration:
- src/hooks/useRadixTourDialog.ts
- src/dialog/DialogRegistryContext.tsx
- src/motion/animationAdapter.tsx
- Motion:
- src/motion/useHudMotion.ts
- src/router/routeGating.ts
- Router:
- src/router/*Adapter.tsx
- src/router/tanstackRouterSync.tsx
- src/devtools/*
- DevTools:
-
Run from repo root:
`bash`
pnpm --filter @flowsterix/react test
pnpm --filter @flowsterix/react typecheck
pnpm --filter @flowsterix/react build
Important constraints:
- package exports point to distdist
- package publishes only
- runtime verification in consuming apps may require rebuilding this package
1. Confirm runtime state:
- activeFlowId
- active step id
- flow status
2. Confirm target state:
- statusvisibility
- rectSource
- lastResolvedRect
-
3. Confirm handoff behavior:
- cached anchor existence
- live rect visibility gate
- settle-by-time or settle-by-speed gate status
4. Confirm motion mode:
- spring/tween setting
- reduced-motion adapter selection
5. Confirm build state:
- source changes reflected in dist
- consuming app restarted when needed
- src/hooks/__tests__/scrollMargin.test.tssrc/hooks/__tests__/useBodyScrollLock.test.tsx
- src/hooks/__tests__/useConstrainedScrollLock.test.ts
- src/hooks/__tests__/useHiddenTargetFallback.test.tsx
- src/hooks/__tests__/waitForPredicate.test.ts
- src/components/__tests__/TourFocusManager.test.tsx
-
When changing behavior:
- add or update deterministic tests around the changed path
- prefer fake timers for time-gated transitions
- validate both overlay and popover when changing handoff policy
1. Implement code changes and tests.
2. Run:
- pnpm --filter @flowsterix/react testpnpm --filter @flowsterix/react typecheck
- pnpm --filter @flowsterix/react build
- CHANGELOG.md`.
3. Update
4. Update this README when:
- exports change
- concepts or invariants change
- tuning constants/heuristics change
5. Validate at least one real consuming app path.