diff --git a/packages/dashboard/app/components/AgentDetailView.css b/packages/dashboard/app/components/AgentDetailView.css index 6eeab880fb..0fb2591b66 100644 --- a/packages/dashboard/app/components/AgentDetailView.css +++ b/packages/dashboard/app/components/AgentDetailView.css @@ -234,6 +234,11 @@ gap: var(--space-sm); } +/* +FNXC:AgentDetailView 2026-06-14-11:22: +The mobile global `* { touch-action: pan-y; }` lock from FN-6365 prevents horizontal swipe gestures unless each known horizontal scroller opts back into pan-x. +The overflowing agent-detail tab strip must keep horizontal touch panning enabled so all tabs remain reachable on narrow touch viewports (FN-6450). +*/ .agent-detail-tabs { display: flex; gap: var(--space-xs); @@ -242,6 +247,7 @@ background: var(--bg-secondary); flex-shrink: 0; overflow-x: auto; + touch-action: pan-x pan-y; -webkit-overflow-scrolling: touch; scrollbar-width: none; } diff --git a/packages/dashboard/app/components/__tests__/AgentDetailView.mobile-scroll.test.tsx b/packages/dashboard/app/components/__tests__/AgentDetailView.mobile-scroll.test.tsx index 8045ba98ef..d6c35f183a 100644 --- a/packages/dashboard/app/components/__tests__/AgentDetailView.mobile-scroll.test.tsx +++ b/packages/dashboard/app/components/__tests__/AgentDetailView.mobile-scroll.test.tsx @@ -47,6 +47,21 @@ describe("AgentDetailView mobile scroll regression (FN-4231)", () => { expect(window.getComputedStyle(footerEl).flexShrink).toBe("0"); }); + it("tabs accept horizontal touch panning on mobile (FN-6450)", async () => { + render(); + + await waitFor(() => { + expect(document.querySelector(".agent-detail-tabs")).toBeTruthy(); + }); + + const tabsEl = document.querySelector(".agent-detail-tabs") as HTMLElement; + const tabsStyle = window.getComputedStyle(tabsEl); + + expect(tabsStyle.touchAction).toBe("pan-x pan-y"); + expect(tabsStyle.touchAction).toContain("pan-x"); + expect(tabsStyle.overflowX).toBe("auto"); + }); + it("tabs are horizontally scrollable at tablet widths (FN-6209)", async () => { Object.defineProperty(window, "matchMedia", { configurable: true,