diff --git a/apps/ui/src/components/ui/path-input.tsx b/apps/ui/src/components/ui/path-input.tsx index c9f79f34..73eefd7c 100644 --- a/apps/ui/src/components/ui/path-input.tsx +++ b/apps/ui/src/components/ui/path-input.tsx @@ -212,7 +212,7 @@ function PathInput({ // Global keyboard shortcut to activate search (/) useEffect(() => { const handleGlobalKeyDown = (e: globalThis.KeyboardEvent) => { - // Activate search with '/' key (unless in an input field) + // Activate search with '/' key (unless in an input field or contenteditable) if ( e.key === '/' && !isEditing && @@ -230,7 +230,9 @@ function PathInput({ } }; - window.addEventListener('keydown', handleGlobalKeyDown, true); // Use capture phase for ESC handling and prevent parent modal from closing when search is open + // Use capture phase to intercept ESC before parent modal handlers + // This allows us to close search first, then let ESC bubble to close modal on second press + window.addEventListener('keydown', handleGlobalKeyDown, true); return () => window.removeEventListener('keydown', handleGlobalKeyDown, true); }, [isEditing, isSearchOpen, entries.length]); @@ -251,6 +253,21 @@ function PathInput({ const breadcrumbs = useMemo(() => parseBreadcrumbs(currentPath), [currentPath]); + const entryItems = useMemo( + () => + entries.map((entry) => ( + handleSelectEntry(entry)}> + {entry.isDirectory ? ( + + ) : ( + + )} + {entry.name} + + )), + [entries, handleSelectEntry] + ); + const showBreadcrumbs = currentPath && !isEditing && !loading && !error; return ( @@ -314,22 +331,7 @@ function PathInput({ No files or directories found - - {entries.map((entry) => ( - handleSelectEntry(entry)} - > - {entry.isDirectory ? ( - - ) : ( - - )} - {entry.name} - - ))} - + {entryItems}