Skip to content

Commit 7fddadf

Browse files
committed
fix(tour): address PR review comments
- Move autoStartAttempted.add() inside timer callback to prevent blocking auto-start when tour first mounts while disabled - Memoize setJoyrideRef with useCallback to prevent ref churn - Remove unused joyrideRef
1 parent 4deabfc commit 7fddadf

File tree

2 files changed

+19
-17
lines changed

2 files changed

+19
-17
lines changed

apps/sim/app/workspace/[workspaceId]/components/product-tour/tour-shared.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { createContext, useContext, useEffect, useRef, useState } from 'react'
3+
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
44
import type { TooltipRenderProps } from 'react-joyride'
55
import { TourTooltip } from '@/components/emcn'
66

@@ -60,7 +60,6 @@ export function TourTooltipAdapter({
6060
}: TooltipRenderProps) {
6161
const { isTooltipVisible, isEntrance, totalSteps } = useContext(TourStateContext)
6262
const [targetEl, setTargetEl] = useState<HTMLElement | null>(null)
63-
const joyrideRef = useRef<HTMLDivElement | null>(null)
6463

6564
useEffect(() => {
6665
const { target } = step
@@ -76,17 +75,21 @@ export function TourTooltipAdapter({
7675
/**
7776
* Forwards the Joyride tooltip ref safely, handling both
7877
* callback refs and RefObject refs from the library.
78+
* Memoized to prevent ref churn (null → node cycling) on re-renders.
7979
*/
80-
const setJoyrideRef = (node: HTMLDivElement | null) => {
81-
joyrideRef.current = node
82-
const { ref } = tooltipProps
83-
if (!ref) return
84-
if (typeof ref === 'function') {
85-
ref(node)
86-
} else {
87-
;(ref as React.MutableRefObject<HTMLDivElement | null>).current = node
88-
}
89-
}
80+
const setJoyrideRef = useCallback(
81+
(node: HTMLDivElement | null) => {
82+
const { ref } = tooltipProps
83+
if (!ref) return
84+
if (typeof ref === 'function') {
85+
ref(node)
86+
} else {
87+
;(ref as React.MutableRefObject<HTMLDivElement | null>).current = node
88+
}
89+
},
90+
// eslint-disable-next-line react-hooks/exhaustive-deps
91+
[tooltipProps.ref]
92+
)
9093

9194
const placement = mapPlacement(step.placement)
9295

apps/sim/app/workspace/[workspaceId]/components/product-tour/use-tour.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,12 @@ export function useTour({
174174

175175
/** Auto-start on first visit (once per page session per tour) */
176176
useEffect(() => {
177-
if (autoStartAttempted.has(storageKey)) return
178-
autoStartAttempted.add(storageKey)
177+
if (disabled || autoStartAttempted.has(storageKey) || isTourCompleted(storageKey)) return
179178

180179
const timer = setTimeout(() => {
181-
if (disabledRef.current || isTourCompleted(storageKey)) return
180+
if (disabledRef.current) return
182181

182+
autoStartAttempted.add(storageKey)
183183
setStepIndex(0)
184184
setIsEntrance(true)
185185
setIsTooltipVisible(false)
@@ -189,8 +189,7 @@ export function useTour({
189189
}, autoStartDelay)
190190

191191
return () => clearTimeout(timer)
192-
// eslint-disable-next-line react-hooks/exhaustive-deps
193-
}, [])
192+
}, [disabled, storageKey, autoStartDelay, tourName, scheduleReveal])
194193

195194
/** Listen for manual trigger events */
196195
useEffect(() => {

0 commit comments

Comments
 (0)