Reintroduce recipe button next to films
This commit is contained in:
parent
ad1bb5e95c
commit
7d7b05c742
@ -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({
|
||||
? <Badge
|
||||
type="small"
|
||||
contrast={contrast}
|
||||
className='translate-y-[-0.5px]'
|
||||
className="translate-y-[-0.5px]"
|
||||
uppercase
|
||||
interactive
|
||||
>
|
||||
{renderLabel}
|
||||
</Badge>
|
||||
: <span className={clsx(
|
||||
'text-content',
|
||||
truncate && 'inline-flex max-w-full *:truncate',
|
||||
'decoration-dotted underline-offset-[4px] underline-main',
|
||||
'decoration-dotted underline-offset-[4px]',
|
||||
'decoration-gray-300 dark:decoration-gray-600',
|
||||
)}>
|
||||
{renderLabel}
|
||||
|
||||
@ -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<ComponentProps<typeof PhotoRecipeOverlayButton>>
|
||||
& EntityLinkExternalProps) {
|
||||
const { small, medium, large } = labelForFilm(film);
|
||||
|
||||
return (
|
||||
@ -41,6 +46,11 @@ export default function PhotoFilm({
|
||||
type={type}
|
||||
badged={badged}
|
||||
contrast={contrast}
|
||||
action={toggleRecipeOverlay &&
|
||||
<PhotoRecipeOverlayButton {...{
|
||||
toggleRecipeOverlay,
|
||||
isShowingRecipeOverlay,
|
||||
}} />}
|
||||
hoverEntity={countOnHover}
|
||||
iconWide={isStringFujifilmSimulation(film)}
|
||||
/>
|
||||
|
||||
@ -105,6 +105,7 @@ export default function PhotoLarge({
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const refZoomControls = useRef<ZoomControlsRef>(null);
|
||||
const refPhotoRecipe = useRef<HTMLDivElement>(null);
|
||||
const refPhotoFilm = useRef<HTMLDivElement>(null);
|
||||
|
||||
const {
|
||||
areZoomControlsShown,
|
||||
@ -130,9 +131,12 @@ export default function PhotoLarge({
|
||||
, []);
|
||||
|
||||
const refRecipe = useRef<HTMLDivElement>(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',
|
||||
)}>
|
||||
<AnimatePresence>
|
||||
{(shouldShowRecipeOverlay || shouldDebugRecipeOverlays) &&
|
||||
{(isShowingRecipeOverlay || shouldDebugRecipeOverlays) &&
|
||||
photo.recipeData &&
|
||||
photo.film &&
|
||||
<PhotoRecipeOverlay
|
||||
@ -336,7 +340,7 @@ export default function PhotoLarge({
|
||||
prefetch={prefetchRelatedLinks}
|
||||
countOnHover={recipeCount}
|
||||
toggleRecipeOverlay={toggleRecipeOverlay}
|
||||
shouldShowRecipeOverlay={shouldShowRecipeOverlay}
|
||||
isShowingRecipeOverlay={isShowingRecipeOverlay}
|
||||
/>}
|
||||
{showTagsContent &&
|
||||
<PhotoTags
|
||||
@ -398,9 +402,14 @@ export default function PhotoLarge({
|
||||
</ul>
|
||||
{showFilmContent && photo.film &&
|
||||
<PhotoFilm
|
||||
ref={refPhotoFilm}
|
||||
film={photo.film}
|
||||
prefetch={prefetchRelatedLinks}
|
||||
countOnHover={filmCount}
|
||||
{...photo.recipeData && !photo.recipeTitle && {
|
||||
toggleRecipeOverlay,
|
||||
isShowingRecipeOverlay,
|
||||
}}
|
||||
/>}
|
||||
</>}
|
||||
<div className={clsx(
|
||||
|
||||
@ -13,7 +13,7 @@ export default function PhotoRecipe({
|
||||
recipe,
|
||||
countOnHover,
|
||||
toggleRecipeOverlay,
|
||||
shouldShowRecipeOverlay,
|
||||
isShowingRecipeOverlay,
|
||||
...props
|
||||
}: {
|
||||
recipe: string
|
||||
@ -38,7 +38,7 @@ export default function PhotoRecipe({
|
||||
action={toggleRecipeOverlay &&
|
||||
<PhotoRecipeOverlayButton {...{
|
||||
toggleRecipeOverlay,
|
||||
shouldShowRecipeOverlay,
|
||||
isShowingRecipeOverlay,
|
||||
}} />}
|
||||
hoverEntity={countOnHover}
|
||||
/>
|
||||
|
||||
@ -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<HTMLButtonElement>(null);
|
||||
|
||||
@ -37,7 +37,7 @@ export default function PhotoRecipeOverlayButton({
|
||||
<FaPlus
|
||||
className={clsx(
|
||||
'transition-transform',
|
||||
shouldShowRecipeOverlay && 'rotate-45',
|
||||
isShowingRecipeOverlay && 'rotate-45',
|
||||
)}
|
||||
size={10}
|
||||
/>
|
||||
|
||||
@ -9,14 +9,14 @@ export default function useRecipeOverlay({
|
||||
ref?: RefObject<HTMLElement | null>,
|
||||
refTriggers?: RefObject<HTMLElement | null>[],
|
||||
}) {
|
||||
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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user