From 7d7b05c7420f097d38322441e60dda39d994c9c8 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Thu, 10 Apr 2025 20:36:38 -0500 Subject: [PATCH] Reintroduce recipe button next to films --- src/components/primitives/EntityLink.tsx | 7 ++++--- src/film/PhotoFilm.tsx | 12 +++++++++++- src/photo/PhotoLarge.tsx | 19 ++++++++++++++----- src/recipe/PhotoRecipe.tsx | 4 ++-- src/recipe/PhotoRecipeOverlayButton.tsx | 6 +++--- src/recipe/useRecipeOverlay.ts | 14 +++++++------- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/components/primitives/EntityLink.tsx b/src/components/primitives/EntityLink.tsx index bedc0a79..5f74f459 100644 --- a/src/components/primitives/EntityLink.tsx +++ b/src/components/primitives/EntityLink.tsx @@ -80,7 +80,7 @@ export default function EntityLink({ 'inline-flex items-center gap-2', 'max-w-full overflow-hidden select-none', // Underline link text when action is hovered - '[&:has(.action:hover)_a>*>*>*]:underline', + '[&:has(.action:hover)_.text-content]:underline', className, )} > @@ -112,15 +112,16 @@ export default function EntityLink({ ? {renderLabel} : {renderLabel} diff --git a/src/film/PhotoFilm.tsx b/src/film/PhotoFilm.tsx index 98d83eab..c035030c 100644 --- a/src/film/PhotoFilm.tsx +++ b/src/film/PhotoFilm.tsx @@ -7,6 +7,8 @@ import EntityLink, { import clsx from 'clsx/lite'; import { labelForFilm } from '.'; import { isStringFujifilmSimulation } from '@/platforms/fujifilm/simulation'; +import PhotoRecipeOverlayButton from '@/recipe/PhotoRecipeOverlayButton'; +import { ComponentProps } from 'react'; export default function PhotoFilm({ film, @@ -14,12 +16,15 @@ export default function PhotoFilm({ badged = true, contrast = 'low', countOnHover, + toggleRecipeOverlay, + isShowingRecipeOverlay, ...props }: { film: string countOnHover?: number recipe?: FujifilmRecipe -} & EntityLinkExternalProps) { +} & Partial> + & EntityLinkExternalProps) { const { small, medium, large } = labelForFilm(film); return ( @@ -41,6 +46,11 @@ export default function PhotoFilm({ type={type} badged={badged} contrast={contrast} + action={toggleRecipeOverlay && + } hoverEntity={countOnHover} iconWide={isStringFujifilmSimulation(film)} /> diff --git a/src/photo/PhotoLarge.tsx b/src/photo/PhotoLarge.tsx index 135747c3..5b55d7c6 100644 --- a/src/photo/PhotoLarge.tsx +++ b/src/photo/PhotoLarge.tsx @@ -105,6 +105,7 @@ export default function PhotoLarge({ const ref = useRef(null); const refZoomControls = useRef(null); const refPhotoRecipe = useRef(null); + const refPhotoFilm = useRef(null); const { areZoomControlsShown, @@ -130,9 +131,12 @@ export default function PhotoLarge({ , []); const refRecipe = useRef(null); - const refTriggers = useMemo(() => [refPhotoRecipe], []); + const refTriggers = useMemo(() => [ + refPhotoRecipe, + refPhotoFilm, + ], []); const { - shouldShowRecipeOverlay, + isShowingRecipeOverlay, toggleRecipeOverlay, hideRecipeOverlay, } = useRecipeOverlay({ @@ -222,11 +226,11 @@ export default function PhotoLarge({ 'flex items-center justify-center', // Allow clicks to pass through to zoom controls // when not showing recipe overlay - !(shouldShowRecipeOverlay || shouldDebugRecipeOverlays) && + !(isShowingRecipeOverlay || shouldDebugRecipeOverlays) && 'pointer-events-none', )}> - {(shouldShowRecipeOverlay || shouldDebugRecipeOverlays) && + {(isShowingRecipeOverlay || shouldDebugRecipeOverlays) && photo.recipeData && photo.film && } {showTagsContent && {showFilmContent && photo.film && } }
} hoverEntity={countOnHover} /> diff --git a/src/recipe/PhotoRecipeOverlayButton.tsx b/src/recipe/PhotoRecipeOverlayButton.tsx index 932c39d7..b6a39df0 100644 --- a/src/recipe/PhotoRecipeOverlayButton.tsx +++ b/src/recipe/PhotoRecipeOverlayButton.tsx @@ -8,11 +8,11 @@ import { useRef } from 'react'; export default function PhotoRecipeOverlayButton({ className, toggleRecipeOverlay, - shouldShowRecipeOverlay, + isShowingRecipeOverlay, }: { className?: string toggleRecipeOverlay: () => void - shouldShowRecipeOverlay?: boolean + isShowingRecipeOverlay?: boolean }) { const ref = useRef(null); @@ -37,7 +37,7 @@ export default function PhotoRecipeOverlayButton({ diff --git a/src/recipe/useRecipeOverlay.ts b/src/recipe/useRecipeOverlay.ts index 291a530d..55217f51 100644 --- a/src/recipe/useRecipeOverlay.ts +++ b/src/recipe/useRecipeOverlay.ts @@ -9,14 +9,14 @@ export default function useRecipeOverlay({ ref?: RefObject, refTriggers?: RefObject[], }) { - const [shouldShowRecipeOverlay, setShouldShowRecipeOverlay] = useState(false); + const [isShowingRecipeOverlay, setIsShowingRecipeOverlay] = useState(false); const showRecipeOverlay = - useCallback(() => setShouldShowRecipeOverlay(true), []); + useCallback(() => setIsShowingRecipeOverlay(true), []); const hideRecipeOverlay = - useCallback(() => setShouldShowRecipeOverlay(false), []); + useCallback(() => setIsShowingRecipeOverlay(false), []); const toggleRecipeOverlay = useCallback(() => - setShouldShowRecipeOverlay(current => !current), + setIsShowingRecipeOverlay(current => !current), []); useClickInsideOutside({ @@ -25,13 +25,13 @@ export default function useRecipeOverlay({ }); useEffect(() => { - if (shouldShowRecipeOverlay && !isElementEntirelyInViewport(ref?.current)) { + if (isShowingRecipeOverlay && !isElementEntirelyInViewport(ref?.current)) { ref?.current?.scrollIntoView({ behavior: 'smooth' }); } - }, [ref, shouldShowRecipeOverlay]); + }, [ref, isShowingRecipeOverlay]); return { - shouldShowRecipeOverlay, + isShowingRecipeOverlay, showRecipeOverlay, hideRecipeOverlay, toggleRecipeOverlay,