From 2e4208e7e1b22451092650079e04c976ce54e0f1 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Tue, 7 May 2024 00:03:28 -0500 Subject: [PATCH] Streamline primitive components --- src/admin/AddButton.tsx | 2 +- src/admin/AdminPhotosTable.tsx | 2 +- src/admin/AdminTagTable.tsx | 2 +- src/admin/EditButton.tsx | 8 +-- src/components/IconButton.tsx | 52 -------------- src/components/IconPathButton.tsx | 69 ------------------- src/components/ShareButton.tsx | 28 +++++--- src/components/SubmitButtonWithStatus.tsx | 2 +- .../primitives}/LoaderButton.tsx | 4 +- .../{ => primitives}/PathLoaderButton.tsx | 10 ++- src/photo/PhotoLarge.tsx | 4 ++ src/photo/PhotoSetHeader.tsx | 8 ++- src/site/SiteChecklistClient.tsx | 13 ++-- src/site/globals.css | 2 +- 14 files changed, 55 insertions(+), 151 deletions(-) delete mode 100644 src/components/IconButton.tsx delete mode 100644 src/components/IconPathButton.tsx rename src/{admin => components/primitives}/LoaderButton.tsx (92%) rename src/components/{ => primitives}/PathLoaderButton.tsx (85%) diff --git a/src/admin/AddButton.tsx b/src/admin/AddButton.tsx index f776b6d7..cba511a6 100644 --- a/src/admin/AddButton.tsx +++ b/src/admin/AddButton.tsx @@ -1,5 +1,5 @@ import { BiImageAdd } from 'react-icons/bi'; -import PathLoaderButton from '@/components/PathLoaderButton'; +import PathLoaderButton from '@/components/primitives/PathLoaderButton'; export default function AddButton({ path, diff --git a/src/admin/AdminPhotosTable.tsx b/src/admin/AdminPhotosTable.tsx index e501c963..f4effb3f 100644 --- a/src/admin/AdminPhotosTable.tsx +++ b/src/admin/AdminPhotosTable.tsx @@ -80,7 +80,7 @@ export default function AdminPhotosTable({ 'flex flex-nowrap', 'gap-2 sm:gap-3 items-center', )}> - + - + } > Edit diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx deleted file mode 100644 index b446752f..00000000 --- a/src/components/IconButton.tsx +++ /dev/null @@ -1,52 +0,0 @@ -'use client'; - -import { clsx } from 'clsx/lite'; -import Spinner, { SpinnerColor } from './Spinner'; - -export default function IconButton({ - icon, - onClick, - isLoading, - className, - spinnerColor, - spinnerSize, -}: { - icon: JSX.Element - onClick?: () => void - isLoading?: boolean - className?: string - spinnerColor?: SpinnerColor - spinnerSize?: number -}) { - return ( - - {!isLoading - ? - : - - } - - ); -} diff --git a/src/components/IconPathButton.tsx b/src/components/IconPathButton.tsx deleted file mode 100644 index 4108d89d..00000000 --- a/src/components/IconPathButton.tsx +++ /dev/null @@ -1,69 +0,0 @@ -'use client'; - -import { useRouter } from 'next/navigation'; -import IconButton from './IconButton'; -import { useEffect, useState, useTransition } from 'react'; -import { clsx } from 'clsx/lite'; -import { SpinnerColor } from './Spinner'; - -export default function IconPathButton({ - icon, - path, - prefetch, - loaderDelay = 250, - shouldScroll = true, - shouldReplace, - spinnerColor, -}: { - icon: JSX.Element - path: string - prefetch?: boolean - loaderDelay?: number - shouldScroll?: boolean - shouldReplace?: boolean - spinnerColor?: SpinnerColor -}) { - 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 ( - startTransition(() => { - if (shouldReplace) { - router.replace(path, { scroll: shouldScroll }); - } else { - router.push(path, { scroll: shouldScroll }); - } - })} - isLoading={shouldShowLoader} - className={clsx( - 'translate-y-[-0.5px]', - 'active:translate-y-[1px]', - 'text-medium', - 'active:text-gray-600 dark:active:text-gray-300', - )} - spinnerColor={spinnerColor ?? 'text'} - /> - ); -} diff --git a/src/components/ShareButton.tsx b/src/components/ShareButton.tsx index 02057aac..b0af3664 100644 --- a/src/components/ShareButton.tsx +++ b/src/components/ShareButton.tsx @@ -1,27 +1,33 @@ import { TbPhotoShare } from 'react-icons/tb'; -import IconPathButton from '@/components/IconPathButton'; +import PathLoaderButton from './primitives/PathLoaderButton'; +import clsx from 'clsx'; export default function ShareButton({ path, prefetch, shouldScroll, dim, + className, }: { path: string prefetch?: boolean shouldScroll?: boolean dim?: boolean + className?: string }) { return ( - , - prefetch, - shouldScroll, - shouldReplace: true, - spinnerColor: 'dim', - }} /> + } + spinnerColor="dim" + prefetch={prefetch} + shouldScroll={shouldScroll} + shouldReplace + styleAsLink + /> ); } diff --git a/src/components/SubmitButtonWithStatus.tsx b/src/components/SubmitButtonWithStatus.tsx index 3cd6a248..502abb22 100644 --- a/src/components/SubmitButtonWithStatus.tsx +++ b/src/components/SubmitButtonWithStatus.tsx @@ -5,7 +5,7 @@ import { useFormStatus } from 'react-dom'; import { SpinnerColor } from './Spinner'; import { clsx } from 'clsx/lite'; import { toastSuccess } from '@/toast'; -import LoaderButton from '@/admin/LoaderButton'; +import LoaderButton from '@/components/primitives/LoaderButton'; interface Props extends HTMLProps { icon?: JSX.Element diff --git a/src/admin/LoaderButton.tsx b/src/components/primitives/LoaderButton.tsx similarity index 92% rename from src/admin/LoaderButton.tsx rename to src/components/primitives/LoaderButton.tsx index b6c55329..1abc4993 100644 --- a/src/admin/LoaderButton.tsx +++ b/src/components/primitives/LoaderButton.tsx @@ -26,7 +26,9 @@ export default function LoaderButton(props: { type={type} className={clsx( className, - styleAsLink ? 'link h-4' : 'h-9', + styleAsLink + ? 'link h-4 hover:text-dim active:text-medium' + : 'h-9', 'inline-flex items-center gap-2 self-start', )} disabled={isLoading || disabled} diff --git a/src/components/PathLoaderButton.tsx b/src/components/primitives/PathLoaderButton.tsx similarity index 85% rename from src/components/PathLoaderButton.tsx rename to src/components/primitives/PathLoaderButton.tsx index ba121f4d..dc61947a 100644 --- a/src/components/PathLoaderButton.tsx +++ b/src/components/primitives/PathLoaderButton.tsx @@ -2,8 +2,8 @@ import { useRouter } from 'next/navigation'; import { ReactNode, useEffect, useState, useTransition } from 'react'; -import { SpinnerColor } from './Spinner'; -import LoaderButton from '@/admin/LoaderButton'; +import { SpinnerColor } from '../Spinner'; +import LoaderButton from '@/components/primitives/LoaderButton'; export default function PathLoaderButton({ path, @@ -13,6 +13,8 @@ export default function PathLoaderButton({ shouldScroll = true, shouldReplace, spinnerColor, + styleAsLink, + className, children, }: { path: string @@ -22,6 +24,8 @@ export default function PathLoaderButton({ shouldScroll?: boolean shouldReplace?: boolean spinnerColor?: SpinnerColor + styleAsLink?: boolean + className?: string children?: ReactNode }) { const router = useRouter(); @@ -50,6 +54,7 @@ export default function PathLoaderButton({ return ( startTransition(() => { if (shouldReplace) { router.replace(path, { scroll: shouldScroll }); @@ -59,6 +64,7 @@ export default function PathLoaderButton({ })} isLoading={shouldShowLoader} spinnerColor={spinnerColor} + styleAsLink={styleAsLink} > {children} diff --git a/src/photo/PhotoLarge.tsx b/src/photo/PhotoLarge.tsx index c094696d..a745b8ab 100644 --- a/src/photo/PhotoLarge.tsx +++ b/src/photo/PhotoLarge.tsx @@ -170,6 +170,10 @@ export default function PhotoLarge({ {photo.takenAtNaiveFormatted} - - } + } ; const renderCopyButton = (label: string, text: string, subtle?: boolean) => - } - className={clsx(subtle && 'text-gray-300 dark:text-gray-700')} + className={clsx( + 'translate-y-[2px]', + subtle && 'text-gray-300 dark:text-gray-700', + )} onClick={() => { navigator.clipboard.writeText(text); toastSuccess(`${label} copied to clipboard`); }} + styleAsLink />; const renderEnvVar = ( @@ -235,11 +239,12 @@ export default function SiteChecklistClient({ {secret}
{renderCopyButton('Secret', secret)} - } onClick={refreshSecret} isLoading={isPendingSecret} spinnerColor="text" + styleAsLink />
diff --git a/src/site/globals.css b/src/site/globals.css index f0fdf1a1..c4b8cf43 100644 --- a/src/site/globals.css +++ b/src/site/globals.css @@ -112,7 +112,7 @@ button.link { @apply p-0 min-h-0 - border-none bg-transparent active:bg-transparent shadow-none + border-none bg-transparent active:bg-transparent shadow-none rounded-none } a, .link { @apply