fix(FN-2043): prevent quick chat from closing on model dropdown clicks

- Update QuickChatFAB outside-click handling to ignore events from the portaled model combobox dropdown
- Add a regression test that verifies clicks inside the model dropdown portal keep the quick chat panel open
- Keep outside body clicks closing behavior intact with test coverage for the control path
- Add a patch changeset for @gsxdsm/fusion describing the quick chat model dropdown dismiss fix
This commit is contained in:
Fusion
2026-04-17 23:51:17 -07:00
committed by gsxdsm
parent 6386cf22a6
commit ea83c4892f
3 changed files with 44 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
---
"@gsxdsm/fusion": patch
---
Fix quick chat panel dismiss when clicking inside the model search dropdown. The dropdown is rendered via `createPortal` to `document.body`, so clicks inside the portaled content were triggering the click-outside handler, incorrectly closing the panel.

View File

@@ -496,6 +496,8 @@ export function QuickChatFAB({ projectId, addToast, showFAB = true, open, onOpen
const target = event.target as Node; const target = event.target as Node;
if (panelRef.current?.contains(target)) return; if (panelRef.current?.contains(target)) return;
if (fabRef.current?.contains(target)) return; if (fabRef.current?.contains(target)) return;
// Don't close if clicking inside a portaled dropdown (e.g., CustomModelDropdown)
if ((target as HTMLElement).closest(".model-combobox-dropdown--portal")) return;
setIsOpen(false); setIsOpen(false);
}; };

View File

@@ -709,6 +709,43 @@ describe("QuickChatFAB", () => {
}); });
}); });
it("does not close panel when clicking inside portaled model dropdown", async () => {
// Render with no agents so it defaults to model mode
mockAgentsHook([]);
render(<QuickChatFAB addToast={addToast} />);
// Open the quick chat panel
fireEvent.click(screen.getByTestId("quick-chat-fab"));
await waitFor(() => {
expect(screen.getByTestId("quick-chat-panel")).toBeDefined();
});
// Click the model combobox trigger to open the dropdown portal
const trigger = screen.getByRole("button", { name: "Select model override" });
fireEvent.click(trigger);
// Verify the portaled dropdown appears
const portalDropdown = await screen.findByTestId("model-combobox-portal");
expect(portalDropdown).toBeDefined();
// Click inside the portaled dropdown (on the search input)
const searchInput = portalDropdown.querySelector("input");
expect(searchInput).not.toBeNull();
fireEvent.mouseDown(searchInput!);
// Panel should still be visible (not closed by the dropdown click)
await waitFor(() => {
expect(screen.getByTestId("quick-chat-panel")).toBeDefined();
});
// Control: clicking outside the panel and dropdown should still close the panel
fireEvent.mouseDown(document.body);
await waitFor(() => {
expect(screen.queryByTestId("quick-chat-panel")).toBeNull();
});
});
it("hides FAB button when showFAB is false", () => { it("hides FAB button when showFAB is false", () => {
render(<QuickChatFAB addToast={addToast} showFAB={false} />); render(<QuickChatFAB addToast={addToast} showFAB={false} />);