From 7cf64404c581670376191f5dc9b474aceb408f8f Mon Sep 17 00:00:00 2001 From: Dicken Date: Mon, 20 Jul 2026 23:24:48 +0200 Subject: [PATCH] Fix: Dropdown schloss nicht bei Klick ausserhalb (Liste war kuenstlich auf volle Bildschirmhoehe gestreckt) --- apps/frontend/src/routes/HomePage.tsx | 18 +++++++++--------- packages/ui/src/ResultsList.tsx | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/frontend/src/routes/HomePage.tsx b/apps/frontend/src/routes/HomePage.tsx index 9553a7b..c779acc 100644 --- a/apps/frontend/src/routes/HomePage.tsx +++ b/apps/frontend/src/routes/HomePage.tsx @@ -97,7 +97,6 @@ export function HomePage() { const { data: readLaterItems } = useReadLater(); const inputRef = useRef(null); const searchContainerRef = useRef(null); - const resultsContainerRef = useRef(null); const queryClient = useQueryClient(); const isSearching = query.trim().length > 0; const isLoading = servicesLoading || bookmarksLoading; @@ -176,15 +175,16 @@ export function HomePage() { }, [isSearching]); // Klick außerhalb von Suchfeld+Trefferliste klappt das Dropdown wieder ein - // (Desktop-Verhalten, Text bleibt erhalten). Trefferliste liegt als - // eigener Scroll-Container außerhalb von searchContainerRef, daher beide - // prüfen - sonst schließt ein Klick auf einen Treffer das Dropdown, bevor - // dessen eigener onClick überhaupt feuert. + // (Desktop-Verhalten, Text bleibt erhalten). Bewusst gegen das tatsächlich + // gerenderte Listbox-Element geprüft (closest('[role="listbox"]')), nicht + // gegen dessen umgebende Scroll-Wrapper-Divs - die sind aus Layoutgründen + // auf volle Resthöhe gestreckt (siehe max-h-full-Trick in ResultsList), + // ein Ref darauf hätte fast den ganzen Bildschirm als "innerhalb" gezählt. useEffect(() => { function onPointerDown(e: MouseEvent) { - const target = e.target as Node; - const insideSearch = searchContainerRef.current?.contains(target); - const insideResults = resultsContainerRef.current?.contains(target); + const target = e.target as HTMLElement; + const insideSearch = searchContainerRef.current?.contains(target) ?? false; + const insideResults = target.closest('[role="listbox"]') !== null; if (!insideSearch && !insideResults) { setResultsVisible(false); } @@ -346,7 +346,7 @@ export function HomePage() { {/* Scrollender Bereich: NUR die Trefferliste scrollt, nicht die ganze Seite */} {isSearching && resultsVisible ? ( -
+
{isLoading ? (

Lade …

diff --git a/packages/ui/src/ResultsList.tsx b/packages/ui/src/ResultsList.tsx index 63176cc..a111a7c 100644 --- a/packages/ui/src/ResultsList.tsx +++ b/packages/ui/src/ResultsList.tsx @@ -56,7 +56,7 @@ export function ResultsList({ return (
    {results.map((item, index) => {