Files
fusion/packages/dashboard/app/utils/__tests__/mobileBarKeyboardFlags.test.ts
gsxdsm e48c75ccc5 fix(mobile-chat): hide executor footer and remove gap above keyboard
On Android the keyboard-open footer (executor status bar) stayed visible
and the off-screen mobile nav bar's reserved padding rendered as an empty
band between the composer and the keyboard. computeMobileBarKeyboardFlags
no longer iOS-gates footerHidden, so both platforms now hide the footer
and drop the reserved footer+nav padding-bottom when the soft keyboard is
up, letting the composer sit flush above the keyboard. footerKeyboardOpen
(the iOS bottom:0 collapse class) stays iOS-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 09:32:53 -07:00

133 lines
4.0 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { computeMobileBarKeyboardFlags } from "../mobileBarKeyboardFlags";
describe("computeMobileBarKeyboardFlags", () => {
it("hides the footer on Android when keyboard is open, but does not apply the iOS bottom:0 collapse class", () => {
// FNXC:MobileChatKeyboardLayout 2026-06-26-09:04:
// Android now matches iOS: the keyboard-open footer is hidden (and its
// reserved padding dropped) so the composer sits flush above the keyboard
// with no dead band. `footerKeyboardOpen` stays iOS-only.
const flags = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: true,
anyModalOpen: false,
overlayOpen: false,
isIOS: false,
});
expect(flags.footerHidden).toBe(true);
expect(flags.navKeyboardOpen).toBe(true);
expect(flags.footerKeyboardOpen).toBe(false);
});
it("hides and collapses footer on iOS when keyboard is open and no overlay is open", () => {
const flags = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: true,
anyModalOpen: false,
overlayOpen: false,
isIOS: true,
});
expect(flags.footerHidden).toBe(true);
expect(flags.navKeyboardOpen).toBe(true);
expect(flags.footerKeyboardOpen).toBe(true);
});
it("keeps footer visible when iOS keyboard is open over a modal", () => {
const flags = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: true,
anyModalOpen: true,
overlayOpen: false,
isIOS: true,
});
expect(flags.footerHidden).toBe(false);
expect(flags.footerKeyboardOpen).toBe(true);
expect(flags.navKeyboardOpen).toBe(true);
});
it("returns all false when keyboard is closed", () => {
const flags = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: false,
anyModalOpen: false,
overlayOpen: false,
isIOS: true,
});
expect(flags).toEqual({
footerHidden: false,
navKeyboardOpen: false,
footerKeyboardOpen: false,
});
});
it("returns all false when not mobile", () => {
const flags = computeMobileBarKeyboardFlags({
isMobile: false,
keyboardOpen: true,
anyModalOpen: false,
overlayOpen: false,
isIOS: true,
});
expect(flags).toEqual({
footerHidden: false,
navKeyboardOpen: false,
footerKeyboardOpen: false,
});
});
it("keeps the board footer visible on iOS when a fullscreen overlay owns the keyboard", () => {
const flags = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: true,
anyModalOpen: false,
overlayOpen: true,
isIOS: true,
});
expect(flags.footerHidden).toBe(false);
expect(flags.navKeyboardOpen).toBe(true);
expect(flags.footerKeyboardOpen).toBe(true);
});
it("keeps Android board-layout behavior unchanged when a fullscreen overlay owns the keyboard", () => {
const flags = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: true,
anyModalOpen: false,
overlayOpen: true,
isIOS: false,
});
expect(flags.footerHidden).toBe(false);
expect(flags.navKeyboardOpen).toBe(true);
expect(flags.footerKeyboardOpen).toBe(false);
});
it("suppresses the original iOS board-shift trigger only when the Quick Chat overlay flag is set", () => {
const originalBoardShiftTrigger = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: true,
anyModalOpen: false,
overlayOpen: false,
isIOS: true,
});
const quickChatOverlayKeyboard = computeMobileBarKeyboardFlags({
isMobile: true,
keyboardOpen: true,
anyModalOpen: false,
overlayOpen: true,
isIOS: true,
});
expect(originalBoardShiftTrigger.footerHidden).toBe(true);
expect(quickChatOverlayKeyboard.footerHidden).toBe(false);
expect(quickChatOverlayKeyboard.navKeyboardOpen).toBe(true);
expect(quickChatOverlayKeyboard.footerKeyboardOpen).toBe(true);
});
});