From 2a07d85baf0aaf97cea64b838f4caf8b1919c85d Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 22 Feb 2026 07:34:49 +0000 Subject: [PATCH] refactor: clean up onboarding scroll, props, and magic values - Move scroll-to-active logic into OnboardingSection via useRef + useEffect (self-contained) - Remove stepId prop, data-step attribute, and querySelector pattern from parent - Extract SCROLL_DELAY_MS and DEFAULT_ICON_SIZE named constants - Remove unused onContinue prop from BeforeLogin - Rename 'triggered' to 'autoSignInCompleted' for clarity Co-Authored-By: yujonglee --- .../components/main/body/onboarding/index.tsx | 23 ++-------------- .../onboarding/account/before-login.tsx | 14 ++++------ .../components/onboarding/account/index.tsx | 2 +- .../src/components/onboarding/final.tsx | 27 ++++++++++--------- .../src/components/onboarding/shared.tsx | 20 ++++++++++---- 5 files changed, 38 insertions(+), 48 deletions(-) diff --git a/apps/desktop/src/components/main/body/onboarding/index.tsx b/apps/desktop/src/components/main/body/onboarding/index.tsx index 1659b4d93b..bffbb36690 100644 --- a/apps/desktop/src/components/main/body/onboarding/index.tsx +++ b/apps/desktop/src/components/main/body/onboarding/index.tsx @@ -1,7 +1,7 @@ import { useQueryClient } from "@tanstack/react-query"; import { platform } from "@tauri-apps/plugin-os"; import { Volume2Icon, VolumeXIcon } from "lucide-react"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { commands as analyticsCommands } from "@hypr/plugin-analytics"; import { commands as sfxCommands } from "@hypr/plugin-sfx"; @@ -115,20 +115,6 @@ export function TabContentOnboarding({ } }, [close, currentTab, queryClient]); - const scrollRef = useRef(null); - - useEffect(() => { - const timeout = setTimeout(() => { - const el = scrollRef.current?.querySelector( - `[data-step="${currentStep}"]`, - ); - if (el) { - el.scrollIntoView({ behavior: "smooth", block: "start" }); - } - }, 350); - return () => clearTimeout(timeout); - }, [currentStep]); - return (
@@ -149,10 +135,9 @@ export function TabContentOnboarding({
-
+
void; -}) { +export function BeforeLogin() { const auth = useAuth(); - const triggered = useAutoTriggerSignin(); + const autoSignInCompleted = useAutoTriggerSignin(); const [showCallbackUrlInput, setShowCallbackUrlInput] = useState(false); return ( @@ -16,14 +12,14 @@ export function BeforeLogin({
- {triggered && ( + {autoSignInCompleted && ( - ))} + {SOCIALS.map(({ label, icon, url, ...rest }) => { + const size = "size" in rest ? rest.size : DEFAULT_ICON_SIZE; + return ( + + ); + })}
void finishOnboarding(onContinue)}> diff --git a/apps/desktop/src/components/onboarding/shared.tsx b/apps/desktop/src/components/onboarding/shared.tsx index c2fe2be4b2..e064571dbc 100644 --- a/apps/desktop/src/components/onboarding/shared.tsx +++ b/apps/desktop/src/components/onboarding/shared.tsx @@ -7,14 +7,15 @@ import { XCircleIcon, } from "lucide-react"; import { AnimatePresence, motion } from "motion/react"; -import type { ReactNode } from "react"; +import { type ReactNode, useEffect, useRef } from "react"; import { cn } from "@hypr/utils"; +const SCROLL_DELAY_MS = 350; + export type SectionStatus = "completed" | "active" | "upcoming"; export function OnboardingSection({ - stepId, title, completedTitle, description, @@ -23,7 +24,6 @@ export function OnboardingSection({ onNext, children, }: { - stepId: string; title: string; completedTitle?: string; description?: string; @@ -32,13 +32,23 @@ export function OnboardingSection({ onNext?: () => void; children: ReactNode; }) { - if (!status || status === "upcoming") return null; + const sectionRef = useRef(null); const isActive = status === "active"; const isCompleted = status === "completed"; + useEffect(() => { + if (!isActive) return; + const timeout = setTimeout(() => { + sectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" }); + }, SCROLL_DELAY_MS); + return () => clearTimeout(timeout); + }, [isActive]); + + if (!status || status === "upcoming") return null; + return ( -
+