From 788c7335de8a272760a875be2cdc514922b264f2 Mon Sep 17 00:00:00 2001 From: mortezaei Date: Mon, 17 Aug 2026 14:04:21 +0330 Subject: [PATCH] refactor(ui): improve input focus handling and test reliability Refactor the focus synchronization logic to include pointer events and ensure test stability when manipulating browser history. - Add `pointerdown` event listener to `useQuestionInputFocusSync` to improve input activation on touch/pointer devices - Extract input activation logic into a dedicated `activateFocusedQuestionInput` function for better readability - Update `QuestionSheet` tests to reset window history state and use asynchronous waiting for `pushState` calls to prevent race conditions --- src/components/Componentes/question-sheet.test.tsx | 4 +++- src/components/Componentes/use-sheet-scroll-lock.ts | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/Componentes/question-sheet.test.tsx b/src/components/Componentes/question-sheet.test.tsx index ce90447..0a3449d 100644 --- a/src/components/Componentes/question-sheet.test.tsx +++ b/src/components/Componentes/question-sheet.test.tsx @@ -30,6 +30,7 @@ vi.mock("@/hooks/marriage/use-section-data", () => ({ describe("QuestionSheet component", () => { afterEach(() => { cleanup(); + window.history.replaceState(null, "", window.location.href); document.body.classList.remove("dropdown-open"); document.body.classList.remove("question-sheet-open"); document.body.classList.remove("question-keyboard-open"); @@ -202,8 +203,9 @@ describe("QuestionSheet component", () => { ); fireEvent.click(screen.getByRole("button", { name: /انتخاب کشور/i })); - expect(pushState).toHaveBeenCalledTimes(1); + await waitFor(() => expect(pushState).toHaveBeenCalledTimes(1)); + window.history.replaceState(null, "", window.location.href); window.dispatchEvent(new PopStateEvent("popstate")); await waitFor(() => { diff --git a/src/components/Componentes/use-sheet-scroll-lock.ts b/src/components/Componentes/use-sheet-scroll-lock.ts index bbce203..a06e343 100644 --- a/src/components/Componentes/use-sheet-scroll-lock.ts +++ b/src/components/Componentes/use-sheet-scroll-lock.ts @@ -157,7 +157,7 @@ function syncKeyboardShift(isOpen: boolean) { */ export function useQuestionInputFocusSync() { useEffect(() => { - const handleFocusIn = (event: FocusEvent) => { + const activateFocusedQuestionInput = (event: Event) => { if (!isKeyboardInputTarget(event.target)) return; const target = event.target as HTMLElement; if (!target.closest('.question-snap-item[aria-current="step"]')) return; @@ -165,6 +165,12 @@ export function useQuestionInputFocusSync() { syncQuestionInputOpenClass(); window.requestAnimationFrame(() => syncKeyboardShift(true)); }; + const handleFocusIn = (event: FocusEvent) => { + activateFocusedQuestionInput(event); + }; + const handlePointerDown = (event: PointerEvent) => { + activateFocusedQuestionInput(event); + }; const handleFocusOut = (event: FocusEvent) => { if (!isKeyboardInputTarget(event.target)) return; window.setTimeout(() => { @@ -198,10 +204,12 @@ export function useQuestionInputFocusSync() { document.addEventListener("focusin", handleFocusIn); document.addEventListener("focusout", handleFocusOut); + document.addEventListener("pointerdown", handlePointerDown, true); window.visualViewport?.addEventListener("resize", handleViewportResize); return () => { document.removeEventListener("focusin", handleFocusIn); document.removeEventListener("focusout", handleFocusOut); + document.removeEventListener("pointerdown", handlePointerDown, true); window.visualViewport?.removeEventListener( "resize", handleViewportResize,