Refine tooltip/more menu interactions
This commit is contained in:
parent
f3cd1c2f8c
commit
99a3fb7ad2
@ -34,10 +34,14 @@ import MoreMenuItem from '@/components/more/MoreMenuItem';
|
||||
export default function AdminAppMenu({
|
||||
active,
|
||||
animateMenuClose,
|
||||
isOpen,
|
||||
setIsOpen,
|
||||
className,
|
||||
}: {
|
||||
active?: boolean
|
||||
animateMenuClose?: boolean
|
||||
isOpen?: boolean
|
||||
setIsOpen?: (isOpen: boolean) => void
|
||||
className?: string
|
||||
}) {
|
||||
const {
|
||||
@ -80,7 +84,7 @@ export default function AdminAppMenu({
|
||||
annotation: `${uploadsCount}`,
|
||||
icon: <IconFolder
|
||||
size={16}
|
||||
className="translate-x-[1px] translate-y-[0.5px]"
|
||||
className="translate-x-[1px] translate-y-[1px]"
|
||||
/>,
|
||||
href: PATH_ADMIN_UPLOADS,
|
||||
});
|
||||
@ -93,13 +97,13 @@ export default function AdminAppMenu({
|
||||
{photosCountNeedSync}
|
||||
</span>
|
||||
<InsightsIndicatorDot
|
||||
className="inline-block translate-y-[-0.5px]"
|
||||
className="inline-block translate-y-[1px]"
|
||||
size="small"
|
||||
/>
|
||||
</>,
|
||||
icon: <IconBroom
|
||||
size={17}
|
||||
className="translate-y-[0.5px]"
|
||||
size={18}
|
||||
className="translate-y-[-0.5px]"
|
||||
/>,
|
||||
href: PATH_ADMIN_PHOTOS_UPDATES,
|
||||
});
|
||||
@ -112,7 +116,7 @@ export default function AdminAppMenu({
|
||||
},
|
||||
icon: <IconPhoto
|
||||
size={15}
|
||||
className="translate-x-[-0.5px] translate-y-[0.5px]"
|
||||
className="translate-x-[-0.5px] translate-y-[1px]"
|
||||
/>,
|
||||
href: PATH_ADMIN_PHOTOS,
|
||||
});
|
||||
@ -123,7 +127,7 @@ export default function AdminAppMenu({
|
||||
annotation: `${tagsCount}`,
|
||||
icon: <IconTag
|
||||
size={15}
|
||||
className="translate-y-[0.5px]"
|
||||
className="translate-y-[1.5px]"
|
||||
/>,
|
||||
href: PATH_ADMIN_TAGS,
|
||||
});
|
||||
@ -134,7 +138,7 @@ export default function AdminAppMenu({
|
||||
annotation: `${recipesCount}`,
|
||||
icon: <IconRecipe
|
||||
size={17}
|
||||
className="translate-x-[-0.5px] translate-y-[0.5px]"
|
||||
className="translate-x-[-0.5px] translate-y-[1px]"
|
||||
/>,
|
||||
href: PATH_ADMIN_RECIPES,
|
||||
});
|
||||
@ -147,7 +151,7 @@ export default function AdminAppMenu({
|
||||
icon: isSelecting
|
||||
? <IoCloseSharp
|
||||
size={18}
|
||||
className="translate-x-[-1px] translate-y-[0.5px]"
|
||||
className="translate-x-[-1px] translate-y-[1px]"
|
||||
/>
|
||||
: <IoMdCheckboxOutline
|
||||
size={16}
|
||||
@ -174,7 +178,7 @@ export default function AdminAppMenu({
|
||||
: 'App Configuration',
|
||||
icon: <AdminAppInfoIcon
|
||||
size="small"
|
||||
className="translate-x-[-0.5px] translate-y-[-0.5px]"
|
||||
className="translate-x-[-0.5px] translate-y-[0.5px]"
|
||||
/>,
|
||||
href: showAppInsightsLink
|
||||
? PATH_ADMIN_INSIGHTS
|
||||
@ -189,6 +193,7 @@ export default function AdminAppMenu({
|
||||
|
||||
return (
|
||||
<MoreMenu
|
||||
{...{ isOpen, setIsOpen }}
|
||||
header={<div className="flex items-center select-none">
|
||||
<span className="inline-flex items-center justify-center w-5 mr-2">
|
||||
{!hasAdminData && isLoadingAdminData
|
||||
@ -226,7 +231,7 @@ export default function AdminAppMenu({
|
||||
'border-medium',
|
||||
className,
|
||||
)}
|
||||
buttonClassName={clsx(
|
||||
classNameButton={clsx(
|
||||
'p-0!',
|
||||
'w-full h-full',
|
||||
'flex items-center justify-center',
|
||||
@ -237,7 +242,7 @@ export default function AdminAppMenu({
|
||||
? 'text-black dark:text-white'
|
||||
: 'text-gray-400 dark:text-gray-600',
|
||||
)}
|
||||
buttonClassNameOpen={clsx(
|
||||
classNameButtonOpen={clsx(
|
||||
'bg-dim text-main!',
|
||||
'[&>*>*]:translate-y-[6px]',
|
||||
!animateMenuClose && '[&>*>*]:duration-300',
|
||||
|
||||
@ -48,7 +48,7 @@ export default function AdminPhotoMenu({
|
||||
label: 'Edit',
|
||||
icon: <IconEdit
|
||||
size={15}
|
||||
className="translate-x-[0.5px] translate-y-[-0.5px]"
|
||||
className="translate-x-[0.5px]"
|
||||
/>,
|
||||
href: pathForAdminPhotoEdit(photo.id),
|
||||
}];
|
||||
@ -57,7 +57,7 @@ export default function AdminPhotoMenu({
|
||||
label: isFav ? 'Unfavorite' : 'Favorite',
|
||||
icon: <IconFavs
|
||||
size={14}
|
||||
className="translate-x-[-1px]"
|
||||
className="translate-x-[-1px] translate-y-[0.5px]"
|
||||
highlight={isFav}
|
||||
/>,
|
||||
action: () => toggleFavoritePhotoAction(
|
||||
@ -70,7 +70,7 @@ export default function AdminPhotoMenu({
|
||||
label: 'Download',
|
||||
icon: <MdOutlineFileDownload
|
||||
size={17}
|
||||
className="translate-x-[-1px] translate-y-[-0.5px]"
|
||||
className="translate-x-[-1px]"
|
||||
/>,
|
||||
href: photo.url,
|
||||
hrefDownloadName: downloadFileNameForPhoto(photo),
|
||||
@ -86,7 +86,9 @@ export default function AdminPhotoMenu({
|
||||
size="small"
|
||||
/>}
|
||||
</span>,
|
||||
icon: <IconGrSync className="translate-x-[-1px]" />,
|
||||
icon: <IconGrSync
|
||||
className="translate-x-[-1px] translate-y-[0.5px]"
|
||||
/>,
|
||||
action: () => syncPhotoAction(photo.id)
|
||||
.then(() => revalidatePhoto?.(photo.id)),
|
||||
});
|
||||
|
||||
@ -12,6 +12,7 @@ import { GRID_HOMEPAGE_ENABLED } from './config';
|
||||
import AdminAppMenu from '@/admin/AdminAppMenu';
|
||||
import Spinner from '@/components/Spinner';
|
||||
import clsx from 'clsx/lite';
|
||||
import { useState } from 'react';
|
||||
|
||||
export type SwitcherSelection = 'feed' | 'grid' | 'admin';
|
||||
|
||||
@ -28,6 +29,8 @@ export default function ViewSwitcher({
|
||||
setIsCommandKOpen,
|
||||
} = useAppState();
|
||||
|
||||
const [isAdminMenuOpen, setIsAdminMenuOpen] = useState(false);
|
||||
|
||||
const renderItemFeed =
|
||||
<SwitcherItem
|
||||
icon={<IconFeed includeTitle={false} />}
|
||||
@ -70,9 +73,12 @@ export default function ViewSwitcher({
|
||||
/>}
|
||||
{isUserSignedIn &&
|
||||
<SwitcherItem
|
||||
icon={<AdminAppMenu />}
|
||||
noPadding
|
||||
icon={<AdminAppMenu
|
||||
isOpen={isAdminMenuOpen}
|
||||
setIsOpen={setIsAdminMenuOpen}
|
||||
/>}
|
||||
tooltip={{ content: 'Admin Menu' }}
|
||||
noPadding
|
||||
/>}
|
||||
</Switcher>
|
||||
<Switcher type="borderless">
|
||||
|
||||
@ -30,8 +30,7 @@ export default function SwitcherItem({
|
||||
}) {
|
||||
const className = clsx(
|
||||
'flex items-center justify-center',
|
||||
'w-[42px] h-full',
|
||||
'py-0.5 px-1.5',
|
||||
'w-[42px] h-[28px]',
|
||||
isInteractive && 'cursor-pointer',
|
||||
isInteractive && 'hover:bg-gray-100/60 active:bg-gray-100',
|
||||
isInteractive && 'dark:hover:bg-gray-900/75 dark:active:bg-gray-900',
|
||||
@ -68,7 +67,10 @@ export default function SwitcherItem({
|
||||
|
||||
return (
|
||||
tooltip
|
||||
? <Tooltip {...tooltip}>
|
||||
? <Tooltip
|
||||
{...tooltip}
|
||||
delayDuration={500}
|
||||
>
|
||||
{content}
|
||||
</Tooltip>
|
||||
: content
|
||||
|
||||
@ -15,12 +15,14 @@ export default function MoreMenu({
|
||||
icon,
|
||||
header,
|
||||
className,
|
||||
buttonClassName,
|
||||
buttonClassNameOpen,
|
||||
classNameButton,
|
||||
classNameButtonOpen,
|
||||
ariaLabel,
|
||||
align = 'end',
|
||||
// Prevent errant clicks from trigger being too close to menu
|
||||
sideOffset = 6,
|
||||
isOpen: isOpenProp,
|
||||
setIsOpen: setIsOpenProp,
|
||||
onOpen,
|
||||
...props
|
||||
}: {
|
||||
@ -28,12 +30,17 @@ export default function MoreMenu({
|
||||
icon?: ReactNode
|
||||
header?: ReactNode
|
||||
className?: string
|
||||
buttonClassName?: string
|
||||
buttonClassNameOpen?: string
|
||||
classNameButton?: string
|
||||
classNameButtonOpen?: string
|
||||
ariaLabel: string
|
||||
isOpen?: boolean
|
||||
setIsOpen?: (isOpen: boolean) => void
|
||||
onOpen?: () => void
|
||||
} & ComponentProps<typeof DropdownMenu.Content>){
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isOpenInternal, setIsOpenInternal] = useState(isOpenProp ?? false);
|
||||
|
||||
const isOpen = isOpenProp ?? isOpenInternal;
|
||||
const setIsOpen = setIsOpenProp ?? setIsOpenInternal;
|
||||
|
||||
const dismissMenu = useCallback(() => {
|
||||
setIsOpen(false);
|
||||
@ -44,7 +51,10 @@ export default function MoreMenu({
|
||||
}, [isOpen, onOpen]);
|
||||
|
||||
return (
|
||||
<DropdownMenu.Root open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DropdownMenu.Root
|
||||
open={isOpen}
|
||||
onOpenChange={setIsOpen}
|
||||
>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<button
|
||||
className={clsx(
|
||||
@ -54,8 +64,8 @@ export default function MoreMenu({
|
||||
'dark:hover:bg-gray-800/75 dark:active:bg-gray-900',
|
||||
'text-dim',
|
||||
'outline-none',
|
||||
buttonClassName,
|
||||
isOpen && buttonClassNameOpen,
|
||||
classNameButton,
|
||||
isOpen && classNameButtonOpen,
|
||||
)}
|
||||
aria-label={ariaLabel}
|
||||
>
|
||||
|
||||
@ -51,7 +51,7 @@ export default function MoreMenuItem({
|
||||
<DropdownMenu.Item
|
||||
disabled={isLoading}
|
||||
className={clsx(
|
||||
'flex items-center h-9',
|
||||
'flex items-center h-8.5',
|
||||
'pl-2 pr-3 py-2 rounded-sm',
|
||||
'select-none hover:outline-hidden',
|
||||
'hover:bg-gray-100/90 active:bg-gray-200/75',
|
||||
@ -108,7 +108,8 @@ export default function MoreMenuItem({
|
||||
isLoading={isLoading || isPending}
|
||||
hideTextOnMobile={false}
|
||||
styleAs="link-without-hover"
|
||||
className="translate-y-[1px]"
|
||||
className="translate-y-[0.5px] text-sm"
|
||||
classNameIcon="translate-y-[-0.5px]!"
|
||||
>
|
||||
<span>
|
||||
{labelComplex ?? label}
|
||||
|
||||
@ -13,6 +13,7 @@ import Tooltip from '../Tooltip';
|
||||
export default function LoaderButton({
|
||||
ref,
|
||||
children,
|
||||
classNameIcon,
|
||||
isLoading,
|
||||
icon,
|
||||
spinnerColor,
|
||||
@ -32,6 +33,7 @@ export default function LoaderButton({
|
||||
...rest
|
||||
}: {
|
||||
ref?: RefObject<HTMLButtonElement | null>
|
||||
classNameIcon?: string
|
||||
isLoading?: boolean
|
||||
icon?: ReactNode
|
||||
spinnerColor?: SpinnerColor
|
||||
@ -79,6 +81,7 @@ export default function LoaderButton({
|
||||
'min-w-[1.25rem] max-h-5',
|
||||
styleAs === 'button' ? 'translate-y-[-0.5px]' : 'translate-y-[0.5px]',
|
||||
'inline-flex justify-center shrink-0',
|
||||
classNameIcon,
|
||||
)}>
|
||||
{isLoading
|
||||
? <Spinner
|
||||
|
||||
Loading…
Reference in New Issue
Block a user