Delay loader icon when opening share modal

This commit is contained in:
Sam Becker 2023-09-13 12:02:04 -05:00
parent 0c8ed7f39c
commit 45a37c9421
2 changed files with 63 additions and 30 deletions

View File

@ -0,0 +1,58 @@
'use client';
import { useRouter } from 'next/navigation';
import IconButton from './IconButton';
import { useEffect, useState, useTransition } from 'react';
import { cc } from '@/utility/css';
export default function IconPathButton({
path,
prefetch,
loaderDelay = 250,
children,
}: {
path: string
prefetch?: boolean
loaderDelay?: number
children: React.ReactNode
}) {
const router = useRouter();
const [isPending, startTransition] = useTransition();
const [shouldShowLoader, setShouldShowLoader] = useState(false);
useEffect(() => {
if (isPending) {
const timeout = setTimeout(() => {
setShouldShowLoader(true);
}, loaderDelay);
return () => clearTimeout(timeout);
} else {
setShouldShowLoader(false);
}
}, [isPending, loaderDelay]);
useEffect(() => {
if (prefetch) {
router.prefetch(path);
}
}, [prefetch, router, path]);
return (
<IconButton
onClick={() => startTransition(() =>
router.push(path))}
isLoading={shouldShowLoader}
className={cc(
'min-h-[1.75rem]',
'active:translate-y-[1px]',
'text-gray-500 active:text-gray-600',
'dark:text-gray-400 dark:active:text-gray-300',
)}
spinnerColor="text"
>
{children}
</IconButton>
);
}

View File

@ -1,12 +1,7 @@
'use client';
import { useRouter } from 'next/navigation';
import { useEffect, useTransition } from 'react';
import { Photo } from '.';
import { routeForPhoto } from '@/site/routes';
import IconButton from '@/components/IconButton';
import { TbPhotoShare } from 'react-icons/tb';
import { cc } from '@/utility/css';
import IconPathButton from '@/components/IconPathButton';
export default function SharePhotoButton({
photo,
@ -15,32 +10,12 @@ export default function SharePhotoButton({
photo: Photo
prefetch?: boolean
}) {
const router = useRouter();
const shareRoute = routeForPhoto(photo, true);
const [isPending, startTransition] = useTransition();
useEffect(() => {
if (prefetch) {
router.prefetch(shareRoute);
}
}, [prefetch, router, shareRoute]);
return (
<IconButton
onClick={() => startTransition(() =>
router.push(shareRoute))}
isLoading={isPending}
className={cc(
'min-h-[1.75rem]',
'active:translate-y-[1px]',
'text-gray-500 active:text-gray-600',
'dark:text-gray-400 dark:active:text-gray-300',
)}
spinnerColor="text"
<IconPathButton
path={routeForPhoto(photo, true)}
prefetch={prefetch}
>
<TbPhotoShare size={17} />
</IconButton>
</IconPathButton>
);
}