Browse Source

refactor: update information sheet keyboard lift mechanism to use margin-bottom instead of transform and ensure focus visibility

master
mortezaei 2 weeks ago
parent
commit
a01fd26ef6
  1. 6
      src/components/Componentes/discount-widget.tsx
  2. 7
      src/components/Componentes/information-sheet.test.tsx
  3. 47
      src/components/Componentes/information-sheet.tsx

6
src/components/Componentes/discount-widget.tsx

@ -157,6 +157,12 @@ export function DiscountWidget({
dir="auto"
value={code}
disabled={discountStatus === "loading" || discountResult !== null}
onFocus={(e) => {
const target = e.target;
setTimeout(() => {
target.scrollIntoView({ behavior: "smooth", block: "center" });
}, 150);
}}
onChange={(e) => {
setCode(e.target.value);
if (discountStatus !== "initial") {

7
src/components/Componentes/information-sheet.test.tsx

@ -23,7 +23,7 @@ describe("InformationSheet", () => {
});
it("should apply smooth keyboard lift when an input inside the sheet receives focus and keyboard height is set", () => {
const { container } = render(
render(
<InformationSheet
isOpen={true}
title="Payment Sheet"
@ -54,8 +54,7 @@ describe("InformationSheet", () => {
);
});
// Verify section transform is applied or calculated
expect(section).toBeDefined();
expect(section?.style.marginBottom).toBe("280px");
});
it("should reset keyboard lift when input loses focus", async () => {
@ -87,6 +86,6 @@ describe("InformationSheet", () => {
// Wait for focusout settlement
await new Promise((r) => setTimeout(r, 60));
expect(section?.style.transform).toBe("");
expect(section?.style.marginBottom).toBe("");
});
});

47
src/components/Componentes/information-sheet.tsx

@ -328,7 +328,7 @@ export function InformationSheet({
return;
}
let currentKbHeight = 0;
let bridgeKbHeight = viewPaddingsBridge.getConfig().keyboardHeight || 0;
let hasFocusedInput = false;
const updateSheetLift = () => {
@ -339,28 +339,21 @@ export function InformationSheet({
? Math.max(0, window.innerHeight - visualViewport.height)
: 0;
const rawHeight = Math.max(currentKbHeight, vpReduction);
const detectedHeight = Math.max(bridgeKbHeight, vpReduction);
const defaultHeight =
typeof window !== "undefined" && window.innerHeight > 0
? Math.round(window.innerHeight * 0.375)
: 285;
const effectiveHeight =
rawHeight > 20
? rawHeight
detectedHeight > 20
? detectedHeight
: hasFocusedInput
? Math.round(window.innerHeight * 0.375)
? defaultHeight
: 0;
if (effectiveHeight > 20 && hasFocusedInput) {
const rect = sheetRef.current.getBoundingClientRect();
const safeTop =
parseFloat(
getComputedStyle(document.documentElement).getPropertyValue(
"--safe-top",
) || "0",
) || 16;
const availableTop = Math.max(0, rect.top - safeTop - 8);
const lift = Math.min(
effectiveHeight,
availableTop + (keyboardLift || 0),
);
setKeyboardLift(Math.max(0, Math.round(lift)));
setKeyboardLift(Math.round(effectiveHeight));
} else if (!hasFocusedInput) {
setKeyboardLift(0);
}
@ -373,6 +366,11 @@ export function InformationSheet({
) {
hasFocusedInput = true;
updateSheetLift();
setTimeout(() => {
if (e.target instanceof HTMLElement) {
e.target.scrollIntoView({ behavior: "smooth", block: "center" });
}
}, 150);
}
};
@ -387,7 +385,7 @@ export function InformationSheet({
};
const unsubscribeConfig = viewPaddingsBridge.subscribeConfig((config) => {
currentKbHeight = config.keyboardHeight;
bridgeKbHeight = config.keyboardHeight;
updateSheetLift();
});
@ -398,14 +396,16 @@ export function InformationSheet({
document.addEventListener("focusin", handleFocusIn);
document.addEventListener("focusout", handleFocusOut);
window.visualViewport?.addEventListener("resize", handleVpResize);
window.visualViewport?.addEventListener("scroll", handleVpResize);
return () => {
document.removeEventListener("focusin", handleFocusIn);
document.removeEventListener("focusout", handleFocusOut);
window.visualViewport?.removeEventListener("resize", handleVpResize);
window.visualViewport?.removeEventListener("scroll", handleVpResize);
unsubscribeConfig();
};
}, [isRendered, keyboardLift]);
}, [isRendered]);
if (!isRendered || !mounted) {
return null;
@ -444,11 +444,8 @@ export function InformationSheet({
ref={sheetRef}
{...props}
style={{
transform:
keyboardLift > 0
? `translate3d(0, -${keyboardLift}px, 0)`
: undefined,
transition: "transform 200ms cubic-bezier(0.16, 1, 0.3, 1)",
marginBottom: keyboardLift > 0 ? `${keyboardLift}px` : undefined,
transition: "margin-bottom 200ms cubic-bezier(0.16, 1, 0.3, 1)",
maxHeight:
keyboardLift > 0
? `calc(100vh - ${keyboardLift + 20}px)`

Loading…
Cancel
Save