From 45d0e09d0f52431592873a3c61470c587e64aead Mon Sep 17 00:00:00 2001 From: fcablik Date: Wed, 7 Feb 2024 14:46:10 +0100 Subject: [PATCH] new search implementation in the index root route + its conditionall custom scrollrestoration component instead of remix.run's provided +fixes +edits --- app/components/custom-scroll-restoration.tsx | 28 ++++ app/components/headers/header-base.tsx | 15 ++ app/components/search-bar.tsx | 28 ++-- app/root.tsx | 20 ++- app/routes/_base+/index.tsx | 141 ++++++++++++++++++- app/routes/_base+/search.tsx | 4 +- app/routes/admin.tsx | 13 ++ 7 files changed, 223 insertions(+), 26 deletions(-) create mode 100644 app/components/custom-scroll-restoration.tsx diff --git a/app/components/custom-scroll-restoration.tsx b/app/components/custom-scroll-restoration.tsx new file mode 100644 index 0000000..cc3904d --- /dev/null +++ b/app/components/custom-scroll-restoration.tsx @@ -0,0 +1,28 @@ +import { useLocation } from '@remix-run/react' +import { useLayoutEffect, useRef, useMemo } from 'react' + +export function CustomScrollRestoration() { + const { pathname, search } = useLocation() + const scrollPositions = useRef<{ [key: string]: number }>({}) + + const paths = useMemo(() => ['/', '', '/?search='], []) + + // Only store scroll position for the specific routes + useLayoutEffect(() => { + if (paths.includes(pathname)) { + scrollPositions.current[pathname + search] = window.scrollY + } + }, [pathname, search, paths]) + + // Only restore scroll position for the specific routes + useLayoutEffect(() => { + if (paths.includes(pathname)) { + const storedPosition = scrollPositions.current[pathname + search] + window.scrollTo(0, storedPosition || 0) + } else { + window.scrollTo(0, 0) // Scroll to top in other routes than "paths" + } + }, [pathname, search, paths]) + + return null +} diff --git a/app/components/headers/header-base.tsx b/app/components/headers/header-base.tsx index a166879..fbb8bca 100644 --- a/app/components/headers/header-base.tsx +++ b/app/components/headers/header-base.tsx @@ -68,6 +68,21 @@ export function HeaderBase({ routeAdmin }: { routeAdmin?: boolean }) { )} + + {({ isActive }) => ( + <> + + + + + )} + + {({ isActive }) => ( <> diff --git a/app/components/search-bar.tsx b/app/components/search-bar.tsx index b8425fa..1dcdcce 100644 --- a/app/components/search-bar.tsx +++ b/app/components/search-bar.tsx @@ -10,10 +10,10 @@ export function SearchBar({ actionUrl, status, autoFocus = false, - autoSubmit = false, + autoSubmit = false, //hides the search status button if True carModelUrl, }: { - actionUrl: 'search' | 'brands' | 'admin/users' | 'pages' | 'carmodels' + actionUrl: '' | 'search' | 'brands' | 'admin/users' | 'pages' | 'carmodels' status: 'idle' | 'pending' | 'success' | 'error' autoFocus?: boolean autoSubmit?: boolean @@ -55,17 +55,19 @@ export function SearchBar({ autoFocus={autoFocus} /> -
- - - Search - -
+ {!autoSubmit && ( +
+ + + Search + +
+ )} ) } diff --git a/app/root.tsx b/app/root.tsx index d4a53a4..23ab256 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -16,6 +16,7 @@ import { Scripts, ScrollRestoration, useLoaderData, + useLocation, useMatches, } from '@remix-run/react' import { withSentry } from '@sentry/remix' @@ -23,6 +24,7 @@ import { AuthenticityTokenProvider } from 'remix-utils/csrf/react' import { HoneypotProvider } from 'remix-utils/honeypot/react' import { z } from 'zod' import { Confetti } from './components/confetti.tsx' +import { CustomScrollRestoration } from './components/custom-scroll-restoration.tsx' import { GeneralErrorBoundary } from './components/error-boundary.tsx' import { FooterBase } from './components/footers/footer-base.tsx' import { HeaderBase } from './components/headers/header-base.tsx' @@ -194,16 +196,22 @@ function Document({ theme?: Theme env?: Record }) { + const { pathname } = useLocation() + const paths = ['/', '', '/?search='] + return ( - + - + {children}