From caeb9f989f829afa4f938a58acc21e32a5e2cd66 Mon Sep 17 00:00:00 2001 From: Froidefond Julien Date: Sun, 29 Mar 2026 18:08:25 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20conserver=20le=20focus=20du=20champ=20de?= =?UTF-8?q?=20recherche=20apr=C3=A8s=20navigation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le form ne remount plus lors de nos propres navigations (recherche, filtres, clear) — le focus est préservé. Le remount ne se fait que lors de navigations externes (back/forward du navigateur) pour syncer les valeurs. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../app/components/LiveSearchForm.tsx | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/backoffice/app/components/LiveSearchForm.tsx b/apps/backoffice/app/components/LiveSearchForm.tsx index 2a504be..1e9193f 100644 --- a/apps/backoffice/app/components/LiveSearchForm.tsx +++ b/apps/backoffice/app/components/LiveSearchForm.tsx @@ -97,10 +97,12 @@ export function LiveSearchForm({ fields, basePath, debounceMs = 300 }: LiveSearc if (timerRef.current) clearTimeout(timerRef.current); if (immediate) { saveFilters(); + isOwnNavRef.current = true; startTransition(() => { router.replace(buildUrl() as any); }); } else { timerRef.current = setTimeout(() => { saveFilters(); + isOwnNavRef.current = true; startTransition(() => { router.replace(buildUrl() as any); }); }, debounceMs); } @@ -120,18 +122,31 @@ export function LiveSearchForm({ fields, basePath, debounceMs = 300 }: LiveSearc const textFields = fields.filter((f) => f.type === "text"); const selectFields = fields.filter((f) => f.type === "select"); - // Force remount when URL params change externally (back/forward, cookie redirect) - // so that defaultValue stays in sync with the URL. - const formKey = searchParams.toString(); + // Track whether the current navigation was initiated by us (not back/forward) + const isOwnNavRef = useRef(false); + + // Force remount only on external navigation (back/forward, cookie redirect) + // Our own navigations skip remount to preserve focus. + const prevParamsRef = useRef(searchParams.toString()); + const formKey = useRef(0); + const currentParams = searchParams.toString(); + if (currentParams !== prevParamsRef.current) { + if (!isOwnNavRef.current) { + formKey.current += 1; // External nav → remount + } + isOwnNavRef.current = false; + prevParamsRef.current = currentParams; + } return (
{ e.preventDefault(); if (timerRef.current) clearTimeout(timerRef.current); saveFilters(); + isOwnNavRef.current = true; startTransition(() => { router.replace(buildUrl() as any); }); }} className="space-y-4" @@ -191,6 +206,7 @@ export function LiveSearchForm({ fields, basePath, debounceMs = 300 }: LiveSearc onClick={() => { formRef.current?.reset(); try { deleteCookie(cookieName); } catch {} + isOwnNavRef.current = true; startTransition(() => { router.replace(basePath as any); }); }} className="