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,
} from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { updateQuestionKeyboardHeight } from "./question-viewport-coordinator";
import { QuestionSnapList } from "./question-snap-list";
import {
computeQuestionLift,
updateQuestionKeyboardHeight,
} from "./question-viewport-coordinator";
vi.mock("@/translations/provider", () => ({
useI18n: () => ({ dictionary: {} }),
@ -20,6 +23,25 @@ describe("QuestionSnapList keyboard interaction", () => {
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", () => {
render(
<QuestionSnapList>
@ -74,9 +96,7 @@ describe("QuestionSnapList keyboard interaction", () => {
expect(firstInput).not.toHaveFocus();
expect(secondInput).not.toHaveFocus();
expect(
document.documentElement.style.getPropertyValue(
"--question-lift-y",
),
document.documentElement.style.getPropertyValue("--question-lift-y"),
).toBe("0px");
});
});
@ -147,7 +167,9 @@ describe("QuestionSnapList keyboard interaction", () => {
input.focus();
updateQuestionKeyboardHeight(300);
await waitFor(() => expect(document.body).toHaveClass("question-keyboard-open"));
await waitFor(() =>
expect(document.body).toHaveClass("question-keyboard-open"),
);
updateQuestionKeyboardHeight(0);
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);
}
function isKeyboardInputTarget(target: EventTarget | null): target is HTMLElement {
function isKeyboardInputTarget(
target: EventTarget | null,
): target is HTMLElement {
if (target instanceof HTMLTextAreaElement) {
return !target.disabled && !target.readOnly;
}
@ -82,10 +84,7 @@ export function isActiveQuestionKeyboardInput(
function setLift(nextLift: number) {
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(
"question-keyboard-open",
currentLift > 0 && keyboardVisible && activeQuestionInput !== null,
@ -220,7 +219,8 @@ export function useQuestionViewportCoordinator() {
});
const handleViewportResize = () => {
const viewportHeight = window.visualViewport?.height ?? window.innerHeight;
const viewportHeight =
window.visualViewport?.height ?? window.innerHeight;
const reduction = closedViewportHeight - viewportHeight;
if (reduction > KEYBOARD_THRESHOLD) {
@ -246,7 +246,10 @@ export function useQuestionViewportCoordinator() {
return () => {
document.removeEventListener("focusin", handleFocusIn);
document.removeEventListener("focusout", handleFocusOut);
window.visualViewport?.removeEventListener("resize", handleViewportResize);
window.visualViewport?.removeEventListener(
"resize",
handleViewportResize,
);
unsubscribeConfig();
resetQuestionKeyboardState();
};

Loading…
Cancel
Save