|
|
@ -331,11 +331,19 @@ export function InformationSheet({ |
|
|
const KEYBOARD_THRESHOLD = 20; |
|
|
const KEYBOARD_THRESHOLD = 20; |
|
|
let keyboardVisible = false; |
|
|
let keyboardVisible = false; |
|
|
let keyboardHeight = 0; |
|
|
let keyboardHeight = 0; |
|
|
|
|
|
let lastKeyboardHeight = 0; |
|
|
let activeInput: HTMLElement | null = null; |
|
|
let activeInput: HTMLElement | null = null; |
|
|
let currentLift = 0; |
|
|
let currentLift = 0; |
|
|
let animFrame: number | null = null; |
|
|
let animFrame: number | null = null; |
|
|
let closedVpHeight = window.visualViewport?.height ?? window.innerHeight; |
|
|
let closedVpHeight = window.visualViewport?.height ?? window.innerHeight; |
|
|
|
|
|
|
|
|
|
|
|
const getDefaultKeyboardHeight = (): number => { |
|
|
|
|
|
if (typeof window !== "undefined" && window.innerHeight > 0) { |
|
|
|
|
|
return Math.round(window.innerHeight * 0.375); |
|
|
|
|
|
} |
|
|
|
|
|
return 285; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
const setLift = (nextLift: number) => { |
|
|
const setLift = (nextLift: number) => { |
|
|
currentLift = Math.max(0, Math.round(nextLift)); |
|
|
currentLift = Math.max(0, Math.round(nextLift)); |
|
|
setKeyboardLift(currentLift); |
|
|
setKeyboardLift(currentLift); |
|
|
@ -349,16 +357,18 @@ export function InformationSheet({ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 1. Calculate keyboard visible bottom limit
|
|
|
// 1. Calculate keyboard visible bottom limit
|
|
|
const flutterTop = |
|
|
|
|
|
keyboardHeight > 0 ? window.innerHeight - keyboardHeight : null; |
|
|
|
|
|
|
|
|
const fullKeyboardHeight = |
|
|
|
|
|
lastKeyboardHeight > 200 |
|
|
|
|
|
? lastKeyboardHeight |
|
|
|
|
|
: getDefaultKeyboardHeight(); |
|
|
|
|
|
const targetHeight = Math.max(keyboardHeight, fullKeyboardHeight); |
|
|
|
|
|
|
|
|
|
|
|
const flutterTop = window.innerHeight - targetHeight; |
|
|
const viewport = window.visualViewport; |
|
|
const viewport = window.visualViewport; |
|
|
const viewportBottom = viewport |
|
|
const viewportBottom = viewport |
|
|
? viewport.offsetTop + viewport.height |
|
|
? viewport.offsetTop + viewport.height |
|
|
: window.innerHeight; |
|
|
: window.innerHeight; |
|
|
const visibleBottom = |
|
|
|
|
|
flutterTop !== null |
|
|
|
|
|
? Math.min(flutterTop, viewportBottom) |
|
|
|
|
|
: viewportBottom; |
|
|
|
|
|
|
|
|
const visibleBottom = Math.min(flutterTop, viewportBottom); |
|
|
|
|
|
|
|
|
// 2. Calculate sheet base geometry (without current lift)
|
|
|
// 2. Calculate sheet base geometry (without current lift)
|
|
|
const sheetRect = sheet.getBoundingClientRect(); |
|
|
const sheetRect = sheet.getBoundingClientRect(); |
|
|
@ -400,14 +410,12 @@ export function InformationSheet({ |
|
|
isKeyboardInputTarget(e.target) |
|
|
isKeyboardInputTarget(e.target) |
|
|
) { |
|
|
) { |
|
|
activeInput = e.target; |
|
|
activeInput = e.target; |
|
|
const currentVpHeight = |
|
|
|
|
|
window.visualViewport?.height ?? window.innerHeight; |
|
|
|
|
|
if ( |
|
|
|
|
|
keyboardHeight > 0 || |
|
|
|
|
|
closedVpHeight - currentVpHeight > KEYBOARD_THRESHOLD |
|
|
|
|
|
) { |
|
|
|
|
|
keyboardVisible = true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
keyboardVisible = true; |
|
|
|
|
|
const expectedHeight = |
|
|
|
|
|
lastKeyboardHeight > 200 |
|
|
|
|
|
? lastKeyboardHeight |
|
|
|
|
|
: getDefaultKeyboardHeight(); |
|
|
|
|
|
keyboardHeight = Math.max(keyboardHeight, expectedHeight); |
|
|
scheduleUpdate(); |
|
|
scheduleUpdate(); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
@ -421,6 +429,7 @@ export function InformationSheet({ |
|
|
: null; |
|
|
: null; |
|
|
if (!activeInput) { |
|
|
if (!activeInput) { |
|
|
keyboardVisible = false; |
|
|
keyboardVisible = false; |
|
|
|
|
|
keyboardHeight = 0; |
|
|
setLift(0); |
|
|
setLift(0); |
|
|
} else { |
|
|
} else { |
|
|
scheduleUpdate(); |
|
|
scheduleUpdate(); |
|
|
@ -431,7 +440,18 @@ export function InformationSheet({ |
|
|
const unsubscribeConfig = viewPaddingsBridge.subscribeConfig((config) => { |
|
|
const unsubscribeConfig = viewPaddingsBridge.subscribeConfig((config) => { |
|
|
const nextHeight = Math.max(0, config.keyboardHeight); |
|
|
const nextHeight = Math.max(0, config.keyboardHeight); |
|
|
if (nextHeight > 0) { |
|
|
if (nextHeight > 0) { |
|
|
keyboardHeight = nextHeight; |
|
|
|
|
|
|
|
|
keyboardVisible = true; |
|
|
|
|
|
const defaultKHeight = getDefaultKeyboardHeight(); |
|
|
|
|
|
const expectedHeight = |
|
|
|
|
|
lastKeyboardHeight > 200 ? lastKeyboardHeight : defaultKHeight; |
|
|
|
|
|
|
|
|
|
|
|
if (activeInput && nextHeight < expectedHeight - 15) { |
|
|
|
|
|
keyboardHeight = expectedHeight; |
|
|
|
|
|
} else { |
|
|
|
|
|
lastKeyboardHeight = Math.max(lastKeyboardHeight, nextHeight); |
|
|
|
|
|
keyboardHeight = nextHeight; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const active = document.activeElement as HTMLElement | null; |
|
|
const active = document.activeElement as HTMLElement | null; |
|
|
if ( |
|
|
if ( |
|
|
!activeInput && |
|
|
!activeInput && |
|
|
@ -441,9 +461,6 @@ export function InformationSheet({ |
|
|
) { |
|
|
) { |
|
|
activeInput = active; |
|
|
activeInput = active; |
|
|
} |
|
|
} |
|
|
if (activeInput) { |
|
|
|
|
|
keyboardVisible = true; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
keyboardHeight = 0; |
|
|
keyboardHeight = 0; |
|
|
keyboardVisible = false; |
|
|
keyboardVisible = false; |
|
|
@ -458,7 +475,10 @@ export function InformationSheet({ |
|
|
if (reduction > KEYBOARD_THRESHOLD) { |
|
|
if (reduction > KEYBOARD_THRESHOLD) { |
|
|
if (activeInput) { |
|
|
if (activeInput) { |
|
|
keyboardVisible = true; |
|
|
keyboardVisible = true; |
|
|
keyboardHeight = reduction; |
|
|
|
|
|
|
|
|
if (reduction > 250) { |
|
|
|
|
|
lastKeyboardHeight = Math.max(lastKeyboardHeight, reduction); |
|
|
|
|
|
keyboardHeight = reduction; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} else if (reduction <= KEYBOARD_THRESHOLD) { |
|
|
} else if (reduction <= KEYBOARD_THRESHOLD) { |
|
|
keyboardVisible = false; |
|
|
keyboardVisible = false; |
|
|
@ -528,10 +548,11 @@ export function InformationSheet({ |
|
|
? `translate3d(0, -${keyboardLift}px, 0)` |
|
|
? `translate3d(0, -${keyboardLift}px, 0)` |
|
|
: undefined, |
|
|
: undefined, |
|
|
transition: "transform 200ms cubic-bezier(0.16, 1, 0.3, 1)", |
|
|
transition: "transform 200ms cubic-bezier(0.16, 1, 0.3, 1)", |
|
|
|
|
|
animation: keyboardLift > 0 ? "none" : undefined, |
|
|
...props.style, |
|
|
...props.style, |
|
|
}} |
|
|
}} |
|
|
className={[ |
|
|
className={[ |
|
|
"relative w-full max-w-[834px] sm:max-w-[540px] rounded-t-[22px] bg-white px-4 pt-4 pb-[max(24px,calc(24px+var(--safe-bottom)))] text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] overflow-y-auto", |
|
|
|
|
|
|
|
|
"relative w-full max-w-[834px] sm:max-w-[540px] rounded-t-[22px] bg-white px-4 pt-4 pb-[max(24px,calc(24px+var(--safe-bottom)))] text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] max-h-[calc(100dvh-var(--safe-top)-16px)] overflow-y-auto", |
|
|
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface", |
|
|
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface", |
|
|
className, |
|
|
className, |
|
|
] |
|
|
] |
|
|
|