diff --git a/app/(stats)/compositions/page.tsx b/app/(stats)/compositions/page.tsx index 03185c17..74476273 100644 --- a/app/(stats)/compositions/page.tsx +++ b/app/(stats)/compositions/page.tsx @@ -29,6 +29,7 @@ import { SortParam } from '@/ui/params/sort-param'; import { Compositions } from './compositions'; import { Suspense } from 'react'; import { toDateRange } from '@/lib/utils/params.utils'; +import { Filter } from '@/ui/params/filter'; // Metadata // --------------- @@ -143,12 +144,12 @@ const CompositionsPage = async ({ searchParams }: PageProps) => { - + - + }>
diff --git a/ui/params/filter.tsx b/ui/params/filter.tsx new file mode 100644 index 00000000..cb738d87 --- /dev/null +++ b/ui/params/filter.tsx @@ -0,0 +1,21 @@ +'use client'; + +import type { ReactNode } from 'react'; + +import { Inline } from '../inline'; +import { Spinner } from '../spinner'; +import { ParamsProvier, useParamsContext } from './useParams'; + +const Loading = () => { + const { pending } = useParamsContext(); + return pending ? : null; +}; + +export const Filter = ({ children }: { children?: ReactNode }) => ( + + + + {children} + + +); diff --git a/ui/params/useParams.tsx b/ui/params/useParams.tsx index 3b3a45cf..97196186 100644 --- a/ui/params/useParams.tsx +++ b/ui/params/useParams.tsx @@ -1,6 +1,29 @@ 'use client'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { createContext, useContext, useTransition } from 'react'; +import type { ReactNode, TransitionStartFunction } from 'react'; + +// Context +// --------------- +const Context = createContext<{ + pending: boolean; + startTransition: TransitionStartFunction; +}>({} as any); + +export const useParamsContext = () => useContext(Context); + +// Provider +// --------------- +export const ParamsProvier = ({ children }: { children?: ReactNode }) => { + const [pending, startTransition] = useTransition(); + + return ( + + {children} + + ); +}; // Hook // --------------- @@ -8,6 +31,7 @@ export const useParams = (keys: Params[]) => { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); + const { startTransition } = useParamsContext(); const params = {} as { [param in Params]: string | null }; keys.forEach(key => { @@ -28,7 +52,9 @@ export const useParams = (keys: Params[]) => { const ps = sp.toString(); const queryString = `${ps.length ? '?' : ''}${ps}`; - router.replace(`${pathname}${queryString}`, { scroll: false }); + startTransition(() => { + router.replace(`${pathname}${queryString}`, { scroll: false }); + }); }; return [params, setParams] as const;