diff --git a/apps/ui/src/components/layout/sidebar/components/project-selector-with-options.tsx b/apps/ui/src/components/layout/sidebar/components/project-selector-with-options.tsx index 7235b8d7..b33a7b6d 100644 --- a/apps/ui/src/components/layout/sidebar/components/project-selector-with-options.tsx +++ b/apps/ui/src/components/layout/sidebar/components/project-selector-with-options.tsx @@ -174,7 +174,7 @@ export function ProjectSelectorWithOptions({ >
{filteredProjects.map((project, index) => ( { + if (isProjectPickerOpen) { + // Focus search input after DOM renders + requestAnimationFrame(() => { + projectSearchInputRef.current?.focus(); + }); + } else { + // Reset search when closing + setProjectSearchQuery(''); + } + }, [isProjectPickerOpen]); + + // Update selection when search query changes (while picker is open) useEffect(() => { if (!isProjectPickerOpen) { - setProjectSearchQuery(''); setSelectedProjectIndex(0); return; } - // When opening, find and select the current project - const currentIndex = currentProject - ? filteredProjects.findIndex((p) => p.id === currentProject.id) - : -1; + if (projectSearchQuery.trim()) { + // When searching, reset to first result + setSelectedProjectIndex(0); + } else { + // When not searching (e.g., on open or search cleared), find and select the current project + const currentIndex = currentProject + ? filteredProjects.findIndex((p) => p.id === currentProject.id) + : -1; + setSelectedProjectIndex(currentIndex !== -1 ? currentIndex : 0); + } + }, [isProjectPickerOpen, projectSearchQuery, filteredProjects, currentProject]); - const initialIndex = currentIndex !== -1 ? currentIndex : 0; - setSelectedProjectIndex(initialIndex); - - // Focus search input and scroll to current project after DOM renders - requestAnimationFrame(() => { - projectSearchInputRef.current?.focus(); - - // Scroll to the current project - const targetProject = filteredProjects[initialIndex]; - if (targetProject) { - scrollToProject(targetProject.id); - } - }); - }, [isProjectPickerOpen, currentProject?.id]); - - // Update selection when search query changes (while picker is open) - useEffect(() => { - if (!isProjectPickerOpen || !projectSearchQuery.trim()) return; - - // When searching, reset to first result - setSelectedProjectIndex(0); - }, [isProjectPickerOpen, projectSearchQuery]); - - // Scroll to highlighted item when selection changes via keyboard + // Scroll to highlighted item when selection changes useEffect(() => { if (!isProjectPickerOpen) return; const targetProject = filteredProjects[selectedProjectIndex]; if (targetProject) { - scrollToProject(targetProject.id); + // Use requestAnimationFrame to ensure DOM is rendered before scrolling + requestAnimationFrame(() => { + scrollToProject(targetProject.id); + }); } }, [selectedProjectIndex, isProjectPickerOpen, filteredProjects, scrollToProject]); diff --git a/apps/ui/src/styles/global.css b/apps/ui/src/styles/global.css index 802b1da0..cd7f8145 100644 --- a/apps/ui/src/styles/global.css +++ b/apps/ui/src/styles/global.css @@ -870,32 +870,6 @@ animation: accordion-up 0.2s ease-out forwards; } -/* Project picker scrollbar styling */ -.project-picker-scroll { - scrollbar-width: thin; - scrollbar-color: var(--muted-foreground) transparent; -} - -.project-picker-scroll::-webkit-scrollbar { - width: 6px; - height: 6px; -} - -.project-picker-scroll::-webkit-scrollbar-track { - background: transparent; - border-radius: 3px; -} - -.project-picker-scroll::-webkit-scrollbar-thumb { - background: var(--muted-foreground); - border-radius: 3px; - min-height: 30px; -} - -.project-picker-scroll::-webkit-scrollbar-thumb:hover { - background: var(--foreground-secondary); -} - /* Terminal scrollbar theming */ .xterm-viewport::-webkit-scrollbar { width: 8px;