Browse Source

feat: implement stable occlusion lift calculation in viewport coordinator with corresponding unit tests

master
mortezaei 1 week ago
parent
commit
19f792bedd
  1. 32
      src/components/Componentes/question-snap-list.test.tsx
  2. 17
      src/components/Componentes/question-viewport-coordinator.ts

32
src/components/Componentes/question-snap-list.test.tsx

@ -6,8 +6,11 @@ import {
waitFor, waitFor,
} from "@testing-library/react"; } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest"; import { afterEach, describe, expect, it, vi } from "vitest";
import { updateQuestionKeyboardHeight } from "./question-viewport-coordinator";
import { QuestionSnapList } from "./question-snap-list"; import { QuestionSnapList } from "./question-snap-list";
import {
computeQuestionLift,
updateQuestionKeyboardHeight,
} from "./question-viewport-coordinator";
vi.mock("@/translations/provider", () => ({ vi.mock("@/translations/provider", () => ({
useI18n: () => ({ dictionary: {} }), useI18n: () => ({ dictionary: {} }),
@ -20,6 +23,25 @@ describe("QuestionSnapList keyboard interaction", () => {
document.documentElement.style.removeProperty("--question-lift-y"); document.documentElement.style.removeProperty("--question-lift-y");
}); });
it("computes a stable occlusion lift without overshoot", () => {
expect(
computeQuestionLift({
baseTop: 300,
baseBottom: 600,
visibleTop: 100,
visibleBottom: 500,
}),
).toBe(150);
expect(
computeQuestionLift({
baseTop: 300,
baseBottom: 600,
visibleTop: 100,
visibleBottom: 800,
}),
).toBe(0);
});
it("does not treat pointer contact as input focus", () => { it("does not treat pointer contact as input focus", () => {
render( render(
<QuestionSnapList> <QuestionSnapList>
@ -74,9 +96,7 @@ describe("QuestionSnapList keyboard interaction", () => {
expect(firstInput).not.toHaveFocus(); expect(firstInput).not.toHaveFocus();
expect(secondInput).not.toHaveFocus(); expect(secondInput).not.toHaveFocus();
expect( expect(
document.documentElement.style.getPropertyValue(
"--question-lift-y",
),
document.documentElement.style.getPropertyValue("--question-lift-y"),
).toBe("0px"); ).toBe("0px");
}); });
}); });
@ -147,7 +167,9 @@ describe("QuestionSnapList keyboard interaction", () => {
input.focus(); input.focus();
updateQuestionKeyboardHeight(300); updateQuestionKeyboardHeight(300);
await waitFor(() => expect(document.body).toHaveClass("question-keyboard-open"));
await waitFor(() =>
expect(document.body).toHaveClass("question-keyboard-open"),
);
updateQuestionKeyboardHeight(0); updateQuestionKeyboardHeight(0);
await waitFor(() => { await waitFor(() => {

17
src/components/Componentes/question-viewport-coordinator.ts

@ -56,7 +56,9 @@ export function computeQuestionLift({
return Math.min(Math.max(centerShift, overlapShift), maxShift); return Math.min(Math.max(centerShift, overlapShift), maxShift);
} }
function isKeyboardInputTarget(target: EventTarget | null): target is HTMLElement {
function isKeyboardInputTarget(
target: EventTarget | null,
): target is HTMLElement {
if (target instanceof HTMLTextAreaElement) { if (target instanceof HTMLTextAreaElement) {
return !target.disabled && !target.readOnly; return !target.disabled && !target.readOnly;
} }
@ -82,10 +84,7 @@ export function isActiveQuestionKeyboardInput(
function setLift(nextLift: number) { function setLift(nextLift: number) {
currentLift = Math.max(0, nextLift); currentLift = Math.max(0, nextLift);
document.documentElement.style.setProperty(
LIFT_VARIABLE,
`${currentLift}px`,
);
document.documentElement.style.setProperty(LIFT_VARIABLE, `${currentLift}px`);
document.body.classList.toggle( document.body.classList.toggle(
"question-keyboard-open", "question-keyboard-open",
currentLift > 0 && keyboardVisible && activeQuestionInput !== null, currentLift > 0 && keyboardVisible && activeQuestionInput !== null,
@ -220,7 +219,8 @@ export function useQuestionViewportCoordinator() {
}); });
const handleViewportResize = () => { const handleViewportResize = () => {
const viewportHeight = window.visualViewport?.height ?? window.innerHeight;
const viewportHeight =
window.visualViewport?.height ?? window.innerHeight;
const reduction = closedViewportHeight - viewportHeight; const reduction = closedViewportHeight - viewportHeight;
if (reduction > KEYBOARD_THRESHOLD) { if (reduction > KEYBOARD_THRESHOLD) {
@ -246,7 +246,10 @@ export function useQuestionViewportCoordinator() {
return () => { return () => {
document.removeEventListener("focusin", handleFocusIn); document.removeEventListener("focusin", handleFocusIn);
document.removeEventListener("focusout", handleFocusOut); document.removeEventListener("focusout", handleFocusOut);
window.visualViewport?.removeEventListener("resize", handleViewportResize);
window.visualViewport?.removeEventListener(
"resize",
handleViewportResize,
);
unsubscribeConfig(); unsubscribeConfig();
resetQuestionKeyboardState(); resetQuestionKeyboardState();
}; };

Loading…
Cancel
Save