Files
fusion/packages/dashboard/app/utils/mobileBarKeyboardFlags.ts
gsxdsm 869a4f77da FN-6329: prevent Quick Chat keyboard board shift
Keep the mobile board layout stable while Quick Chat owns the keyboard viewport.

- Treat fullscreen mobile overlays as suppressors for App-level footer hiding.
- Pass Quick Chat mobile open state into the shared keyboard flag helper.
- Cover iOS, Android, modal, and non-mobile keyboard flag behavior.
- Document the Quick Chat mobile keyboard board-shift root cause and fix.

Files changed:
 .../quick-chat-mobile-keyboard-board-shift.md      | 58 ++++++++++++++++++++++
 packages/dashboard/app/App.tsx                     |  4 +-
 .../utils/__tests__/mobileBarKeyboardFlags.test.ts | 57 ++++++++++++++++++++-
 .../dashboard/app/utils/mobileBarKeyboardFlags.ts  | 10 +++-
 4 files changed, 126 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-6329

Fusion-Task-Lineage: f7c37252-c0ea-44f0-b4e3-5aa2022cf7bc
2026-06-12 19:22:11 -07:00

45 lines
1.4 KiB
TypeScript

export interface MobileBarKeyboardFlagsInput {
isMobile: boolean;
keyboardOpen: boolean;
anyModalOpen: boolean;
/** True when a fullscreen mobile overlay owns keyboard/viewport layout. */
overlayOpen: boolean;
isIOS: boolean;
}
export interface MobileBarKeyboardFlags {
footerHidden: boolean;
navKeyboardOpen: boolean;
footerKeyboardOpen: boolean;
}
/**
* FN-5707: Android uses `interactive-widget=resizes-content`, so the layout
* viewport shrinks with the keyboard and the footer's normal stacked bottom
* position remains correct above the mobile nav. Only iOS should apply the
* footer keyboard-collapse class (`bottom: 0`) used to let the keyboard cover
* bars when visualViewport shifts independently.
*
* Fullscreen mobile overlays (for example Quick Chat's sheet) own their own
* visual viewport handling. Treat them like modals for board-layout padding so
* overlay-local keyboards never shift the underlying board.
*/
export function computeMobileBarKeyboardFlags({
isMobile,
keyboardOpen,
anyModalOpen,
overlayOpen,
isIOS,
}: MobileBarKeyboardFlagsInput): MobileBarKeyboardFlags {
const boardLayoutSuppressed = anyModalOpen || overlayOpen;
const footerHidden = isMobile && keyboardOpen && !boardLayoutSuppressed && isIOS;
const navKeyboardOpen = isMobile && keyboardOpen;
const footerKeyboardOpen = navKeyboardOpen && isIOS;
return {
footerHidden,
navKeyboardOpen,
footerKeyboardOpen,
};
}