Browse Source

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
Dev
mortezaei 1 week ago
parent
commit
788c7335de
  1. 4
      src/components/Componentes/question-sheet.test.tsx
  2. 10
      src/components/Componentes/use-sheet-scroll-lock.ts

4
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(() => {

10
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,

Loading…
Cancel
Save