Merge pull request #1024 from qorexdev/fix/onboarding-animation-state-in-handlers

refactor: move onboarding animation state into event handlers
This commit is contained in:
Rohan Verma 2026-03-28 16:53:36 -07:00 committed by GitHub
commit 7400f215af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -160,6 +160,8 @@ function TourTooltip({
onPrev, onPrev,
onSkip, onSkip,
isDarkMode, isDarkMode,
shouldAnimate,
onAnimationEnd,
}: { }: {
step: TourStep; step: TourStep;
stepIndex: number; stepIndex: number;
@ -170,23 +172,12 @@ function TourTooltip({
onPrev: () => void; onPrev: () => void;
onSkip: () => void; onSkip: () => void;
isDarkMode: boolean; isDarkMode: boolean;
shouldAnimate: boolean;
onAnimationEnd: () => void;
}) { }) {
const [contentKey, setContentKey] = useState(stepIndex);
const [shouldAnimate, setShouldAnimate] = useState(false);
const prevStepIndexRef = useRef(stepIndex);
const isLastStep = stepIndex === totalSteps - 1; const isLastStep = stepIndex === totalSteps - 1;
const isFirstStep = stepIndex === 0; const isFirstStep = stepIndex === 0;
// Update content key when step changes to trigger animation
// Only animate if stepIndex actually changes (not on initial mount)
useEffect(() => {
if (prevStepIndexRef.current !== stepIndex) {
setShouldAnimate(true);
setContentKey(stepIndex);
prevStepIndexRef.current = stepIndex;
}
}, [stepIndex]);
const bgColor = isDarkMode ? "#27272a" : "#ffffff"; const bgColor = isDarkMode ? "#27272a" : "#ffffff";
const textColor = isDarkMode ? "#ffffff" : "#18181b"; const textColor = isDarkMode ? "#ffffff" : "#18181b";
const mutedTextColor = isDarkMode ? "#a1a1aa" : "#71717a"; const mutedTextColor = isDarkMode ? "#a1a1aa" : "#71717a";
@ -358,11 +349,11 @@ function TourTooltip({
> >
{/* Content */} {/* Content */}
<div <div
key={contentKey} key={stepIndex}
style={{ style={{
animation: shouldAnimate ? "fadeInSlide 0.3s ease-out" : "none", animation: shouldAnimate ? "fadeInSlide 0.3s ease-out" : "none",
}} }}
onAnimationEnd={() => setShouldAnimate(false)} onAnimationEnd={onAnimationEnd}
> >
<h3 id="tour-title" className="text-sm font-semibold mb-1.5" style={{ color: textColor }}> <h3 id="tour-title" className="text-sm font-semibold mb-1.5" style={{ color: textColor }}>
{step.title} {step.title}
@ -427,6 +418,7 @@ export function OnboardingTour() {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const [isActive, setIsActive] = useState(false); const [isActive, setIsActive] = useState(false);
const [stepIndex, setStepIndex] = useState(0); const [stepIndex, setStepIndex] = useState(0);
const [shouldAnimate, setShouldAnimate] = useState(false);
const [targetEl, setTargetEl] = useState<Element | null>(null); const [targetEl, setTargetEl] = useState<Element | null>(null);
const [spotlightTargetEl, setSpotlightTargetEl] = useState<Element | null>(null); const [spotlightTargetEl, setSpotlightTargetEl] = useState<Element | null>(null);
const [spotlightStepTarget, setSpotlightStepTarget] = useState<string | null>(null); const [spotlightStepTarget, setSpotlightStepTarget] = useState<string | null>(null);
@ -676,6 +668,7 @@ export function OnboardingTour() {
const handleNext = useCallback(() => { const handleNext = useCallback(() => {
if (stepIndex < TOUR_STEPS.length - 1) { if (stepIndex < TOUR_STEPS.length - 1) {
retryCountRef.current = 0; retryCountRef.current = 0;
setShouldAnimate(true);
setStepIndex(stepIndex + 1); setStepIndex(stepIndex + 1);
} else { } else {
// Tour completed - save to localStorage // Tour completed - save to localStorage
@ -690,6 +683,7 @@ export function OnboardingTour() {
const handlePrev = useCallback(() => { const handlePrev = useCallback(() => {
if (stepIndex > 0) { if (stepIndex > 0) {
retryCountRef.current = 0; retryCountRef.current = 0;
setShouldAnimate(true);
setStepIndex(stepIndex - 1); setStepIndex(stepIndex - 1);
} }
}, [stepIndex]); }, [stepIndex]);
@ -713,6 +707,10 @@ export function OnboardingTour() {
setIsActive(false); setIsActive(false);
}, [user?.id]); }, [user?.id]);
const handleAnimationEnd = useCallback(() => {
setShouldAnimate(false);
}, []);
// Handle escape key // Handle escape key
useEffect(() => { useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => { const handleKeyDown = (e: KeyboardEvent) => {
@ -784,6 +782,8 @@ export function OnboardingTour() {
onPrev={handlePrev} onPrev={handlePrev}
onSkip={handleSkip} onSkip={handleSkip}
isDarkMode={isDarkMode} isDarkMode={isDarkMode}
shouldAnimate={shouldAnimate}
onAnimationEnd={handleAnimationEnd}
/> />
</> </>
)} )}