Add status indicator to CMD-K menu

This commit is contained in:
Sam Becker 2024-05-26 12:36:19 -05:00
parent b5a038fd50
commit 9babc102d4
3 changed files with 80 additions and 30 deletions

View File

@ -18,11 +18,11 @@ import {
PATH_SIGN_IN,
pathForPhoto,
pathForTag,
} from '../site/paths';
import Modal from './Modal';
} from '../../site/paths';
import Modal from '../Modal';
import { clsx } from 'clsx/lite';
import { useDebounce } from 'use-debounce';
import Spinner from './Spinner';
import Spinner from '../Spinner';
import { useRouter } from 'next/navigation';
import { useTheme } from 'next-themes';
import { BiDesktop, BiMoon, BiSun } from 'react-icons/bi';
@ -41,6 +41,7 @@ import { FaCheck } from 'react-icons/fa6';
import { TagsWithMeta, addHiddenToTags, formatTag } from '@/tag';
import { FaTag } from 'react-icons/fa';
import { formatCount, formatCountDescriptive } from '@/utility/string';
import CommandKItem from './CommandKItem';
const LISTENER_KEYDOWN = 'keydown';
const MINIMUM_QUERY_LENGTH = 2;
@ -373,23 +374,17 @@ export default function CommandKClient({
{items.map(({
label,
keywords,
accessory,
annotation,
annotationAria,
accessory,
path,
action,
}) =>
<Command.Item
<CommandKItem
key={`${heading} ${label}`}
label={label}
value={`${heading} ${label}`}
keywords={keywords}
className={clsx(
'px-2',
accessory ? 'py-2' : 'py-1',
'rounded-md cursor-pointer tracking-wide',
'data-[selected=true]:bg-gray-100',
'data-[selected=true]:dark:bg-gray-900/75',
)}
onSelect={() => {
if (path) {
startTransition(() => {
@ -401,23 +396,11 @@ export default function CommandKClient({
action?.();
}
}}
>
<div className="flex items-center gap-2 sm:gap-3">
{accessory}
<span className="grow text-ellipsis truncate">
{label}
</span>
{annotation &&
<span
className="text-dim whitespace-nowrap"
aria-label={annotationAria}
>
<span aria-hidden={Boolean(annotationAria)}>
{annotation}
</span>
</span>}
</div>
</Command.Item>)}
accessory={accessory}
annotation={annotation}
annotationAria={annotationAria}
showSpinner={Boolean(path)}
/>)}
</Command.Group>)}
{footer && !queryLive &&
<div className="text-center text-dim pt-3 sm:pt-4">

View File

@ -0,0 +1,65 @@
import { clsx } from 'clsx/lite';
import { Command } from 'cmdk';
import { ReactNode, useState } from 'react';
import Spinner from '../Spinner';
export default function CommandKItem({
label,
value,
keywords,
onSelect,
accessory,
annotation,
annotationAria,
showSpinner,
}: {
label: string
value: string
keywords?: string[]
onSelect: () => void
accessory?: ReactNode
annotation?: ReactNode
annotationAria?: string
showSpinner?: boolean
}) {
const [isLoading, setIsLoading] = useState(false);
return (
<Command.Item
value={value}
keywords={keywords}
className={clsx (
'px-2',
accessory ? 'py-2' : 'py-1',
'rounded-md cursor-pointer tracking-wide',
'data-[selected=true]:bg-gray-100',
'data-[selected=true]:dark:bg-gray-900/75',
'active:!bg-gray-200/75 active:dark:!bg-gray-800/55',
)}
onSelect={() => {
onSelect?.();
if (showSpinner) {
setIsLoading(true);
}
}}
>
<div className="flex items-center gap-2 sm:gap-3">
{accessory}
<span className="grow text-ellipsis truncate">
{label}
</span>
{annotation && !isLoading &&
<span
className="text-dim whitespace-nowrap"
aria-label={annotationAria}
>
<span aria-hidden={Boolean(annotationAria)}>
{annotation}
</span>
</span>}
{isLoading &&
<Spinner color="text" />}
</div>
</Command.Item>
);
}

View File

@ -1,4 +1,6 @@
import CommandKClient, { CommandKSection } from '@/components/CommandKClient';
import CommandKClient, {
CommandKSection,
} from '@/components/cmdk/CommandKClient';
import {
getPhotosMetaCached,
getUniqueCamerasCached,