From e78203e7fb1a1778cdfb42890995c96bb8c84db5 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Tue, 9 Jun 2026 14:51:22 -0700 Subject: [PATCH] FN-6128: preserve textarea focus on mobile quick-entry buttons Prevent mobile quick-entry touches from stealing focus from the task textarea. - intercept touch interactions on quick-entry action buttons before the browser refocuses them - restore textarea focus after touch-triggered quick-entry actions complete - avoid autofocus in the deps search input when the textarea is already focused - add mobile regression coverage across the full quick-entry action button surface, including disabled buttons Files changed: packages/dashboard/app/components/QuickEntryBox.tsx | 32 +++++- packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx | 123 +++++++++++++++++++++ 2 files changed, 153 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-6128 Fusion-Task-Lineage: 598e6ba5-6e83-426c-9bf2-dd2ac4215092 --- .../app/components/QuickEntryBox.tsx | 32 ++++- .../__tests__/QuickEntryBox.test.tsx | 123 ++++++++++++++++++ 2 files changed, 153 insertions(+), 2 deletions(-) diff --git a/packages/dashboard/app/components/QuickEntryBox.tsx b/packages/dashboard/app/components/QuickEntryBox.tsx index 510250667a..62e6ff1bcf 100644 --- a/packages/dashboard/app/components/QuickEntryBox.tsx +++ b/packages/dashboard/app/components/QuickEntryBox.tsx @@ -104,6 +104,7 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels, const [isDisclosureExpanded, setIsDisclosureExpanded] = useState(true); const textareaRef = useRef(null); const fileInputRef = useRef(null); + const touchButtonRef = useRef(null); const justResetRef = useRef(false); const previousProjectIdRef = useRef(projectId); const [pendingImages, setPendingImages] = useState([]); @@ -1478,7 +1479,34 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels, > {/* All quick-create actions behind single disclosure toggle */} {showExpandedControls && !isSubmitting && ( -
+
{ + const target = e.target; + if (!(target instanceof HTMLElement)) return; + const button = target.closest("button"); + if (button && !button.disabled) { + e.preventDefault(); + touchButtonRef.current = button; + } + }} + onTouchEnd={() => { + const button = touchButtonRef.current; + touchButtonRef.current = null; + if (button && !button.disabled) { + button.click(); + window.setTimeout(() => { + window.setTimeout(() => { + textareaRef.current?.focus({ preventScroll: true }); + }, 0); + }, 0); + } + }} + onTouchCancel={() => { + touchButtonRef.current = null; + }} + >