From 3ae500f93e517f677c7dec54185a06e28141b0c3 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Wed, 5 Jun 2024 20:33:54 -0500 Subject: [PATCH] Make cmd-k item visible while loading --- src/components/cmdk/CommandKClient.tsx | 32 +++++++++++++++-------- src/components/cmdk/CommandKItem.tsx | 35 ++++++++++++++------------ 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/components/cmdk/CommandKClient.tsx b/src/components/cmdk/CommandKClient.tsx index edcbe431..5b87ac46 100644 --- a/src/components/cmdk/CommandKClient.tsx +++ b/src/components/cmdk/CommandKClient.tsx @@ -91,12 +91,16 @@ export default function CommandKClient({ const isOpenRef = useRef(isOpen); const [isPending, startTransition] = useTransition(); + const [keyPending, setKeyPending] = useState(); const shouldCloseAfterPending = useRef(false); useEffect(() => { - if (!isPending && shouldCloseAfterPending.current) { - setIsOpen?.(false); - shouldCloseAfterPending.current = false; + if (!isPending) { + setKeyPending(undefined); + if (shouldCloseAfterPending.current) { + setIsOpen?.(false); + shouldCloseAfterPending.current = false; + } } }, [isPending, setIsOpen]); @@ -312,7 +316,7 @@ export default function CommandKClient({ onClose={() => setIsOpen?.(false)} fast > -
+
setQueryLive(e.currentTarget.value)} @@ -324,6 +328,7 @@ export default function CommandKClient({ 'focus:border-gray-200 focus:dark:border-gray-800', 'placeholder:text-gray-400/80', 'placeholder:dark:text-gray-700', + isPending && 'opacity-20', )} placeholder="Search photos, views, settings ..." disabled={isPending} @@ -356,6 +361,7 @@ export default function CommandKClient({ heading={
{accessory &&
{accessory}
} @@ -379,15 +385,17 @@ export default function CommandKClient({ annotationAria, path, action, - }) => - { + const key = `${heading} ${label}`; + return { if (path) { - startTransition(() => { + setKeyPending(key); + startTransition(async () => { shouldCloseAfterPending.current = true; router.push(path, { scroll: true }); }); @@ -399,8 +407,10 @@ export default function CommandKClient({ accessory={accessory} annotation={annotation} annotationAria={annotationAria} - showSpinner={Boolean(path)} - />)} + loading={key === keyPending} + disabled={isPending && key !== keyPending} + />; + })} )} {footer && !queryLive &&
diff --git a/src/components/cmdk/CommandKItem.tsx b/src/components/cmdk/CommandKItem.tsx index 9f72f423..4e9b0bd5 100644 --- a/src/components/cmdk/CommandKItem.tsx +++ b/src/components/cmdk/CommandKItem.tsx @@ -1,6 +1,6 @@ import { clsx } from 'clsx/lite'; import { Command } from 'cmdk'; -import { ReactNode, useState } from 'react'; +import { ReactNode } from 'react'; import Spinner from '../Spinner'; export default function CommandKItem({ @@ -11,7 +11,8 @@ export default function CommandKItem({ accessory, annotation, annotationAria, - showSpinner, + loading, + disabled, }: { label: string value: string @@ -20,10 +21,9 @@ export default function CommandKItem({ accessory?: ReactNode annotation?: ReactNode annotationAria?: string - showSpinner?: boolean + loading?: boolean + disabled?: boolean }) { - const [isLoading, setIsLoading] = useState(false); - return ( { - onSelect?.(); - if (showSpinner) { - setIsLoading(true); - } - }} + onSelect={onSelect} + disabled={loading || disabled} >
{accessory} {label} - {annotation && !isLoading && + {annotation && !loading && } - {isLoading && - } + {loading && + }
);