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}