feat(FN-3343): add Escape key keyboard handling to modals

This merge delivers v0.17.2 and ships FN-3343 keyboard handling across four dashboard modals (NewTaskModal, SubtaskBreakdownModal, MilestoneSliceInterviewModal, SettingsModal) with mobile CSS overrides, plus keyboard style regression tests for each modal and a minor test alignment for the onboarding

Fusion-Task-Id: FN-3343
This commit is contained in:
Fusion
2026-05-04 01:37:33 -07:00
committed by gsxdsm
parent 3092f89379
commit 2d72eddb9c
10 changed files with 216 additions and 7 deletions

View File

@@ -41,6 +41,15 @@ vi.mock("../../hooks/useConfirm", () => ({
useConfirm: () => ({ confirm: mockConfirm }),
}));
const mockUseMobileKeyboard = vi.fn();
vi.mock("../../hooks/useMobileKeyboard", () => ({
useMobileKeyboard: (...args: unknown[]) => mockUseMobileKeyboard(...args),
}));
vi.mock("../../hooks/useViewportMode", () => ({
useViewportMode: () => "mobile",
}));
function makeTask(id: string): Task {
return {
id,
@@ -77,6 +86,37 @@ describe("NewTaskModal", () => {
vi.clearAllMocks();
mockConfirm.mockReset();
mockConfirm.mockResolvedValue(true);
mockUseMobileKeyboard.mockReturnValue({
keyboardOpen: false,
keyboardOverlap: 0,
viewportHeight: null,
viewportOffsetTop: 0,
});
});
it("applies keyboard CSS variables when mobile keyboard is open", () => {
mockUseMobileKeyboard.mockReturnValue({
keyboardOpen: true,
keyboardOverlap: 250,
viewportHeight: 400,
viewportOffsetTop: 50,
});
const { container } = renderNewTaskModal();
const modal = container.querySelector(".new-task-modal");
expect(mockUseMobileKeyboard).toHaveBeenCalledWith({ enabled: true });
expect(modal?.getAttribute("style")).toContain("--keyboard-overlap: 250px");
expect(modal?.getAttribute("style")).toContain("--vv-height: 400px");
expect(modal?.getAttribute("style")).toContain("--vv-offset-top: 50px");
});
it("does not apply keyboard CSS variables when keyboard is closed", () => {
const { container } = renderNewTaskModal();
const modal = container.querySelector(".new-task-modal");
expect(mockUseMobileKeyboard).toHaveBeenCalledWith({ enabled: true });
expect(modal?.getAttribute("style") ?? "").not.toContain("--keyboard-overlap");
});
it("renders all form fields when open", async () => {